388 lines
		
	
	
		
			19 KiB
		
	
	
	
		
			C#
		
	
	
			
		
		
	
	
			388 lines
		
	
	
		
			19 KiB
		
	
	
	
		
			C#
		
	
	
| using IRaCIS.Application.Interfaces;
 | |
| using IRaCIS.Core.Infra.EFCore;
 | |
| using IRaCIS.Core.Domain.Share;
 | |
| using IRaCIS.Core.Application.Filter;
 | |
| using Microsoft.AspNetCore.Mvc;
 | |
| using IRaCIS.Core.Application.Service.WorkLoad.DTO;
 | |
| using Microsoft.AspNetCore.Authorization;
 | |
| using IRaCIS.Core.Application.Auth;
 | |
| using IRaCIS.Core.Application.Service.Reading.Dto;
 | |
| using MassTransit;
 | |
| using Panda.DynamicWebApi.Attributes;
 | |
| using IRaCIS.Core.Application.Contracts;
 | |
| using IRaCIS.Core.Infra.EFCore.Common;
 | |
| using System.Linq.Dynamic.Core;
 | |
| 
 | |
| namespace IRaCIS.Application.Services
 | |
| {
 | |
|     /// <summary>
 | |
|     /// 生成的阅片模块(在大列表上展示的) 阅片期
 | |
|     /// </summary>
 | |
|     [ApiExplorerSettings(GroupName = "Reading")]
 | |
|     public class ReadModuleService :  BaseService
 | |
|     {
 | |
| 
 | |
|         public IRepository<SubjectVisit> _subjectVisitRepository;
 | |
|         private readonly IRepository<Subject> _subjectRepository;
 | |
|         private readonly IRepository<VisitStage> _visitstageRepository;
 | |
|         private readonly IRepository<User> _userRepository;
 | |
|         private readonly IRepository<Trial> _trialRepository;
 | |
|         private readonly IRepository<VisitTask> _visitTaskRepository;
 | |
|         private readonly IRepository<ClinicalDataTrialSet> _clinicalDataTrialSetRepository;
 | |
|         private readonly IRepository<ReadModuleView> _readModuleViewRepository;
 | |
|         private readonly IRepository<DicomInstance> _dicomInstanceRepository;
 | |
|         private readonly IRepository<NoneDicomStudyFile> _noneDicomStudyFileRepository;
 | |
|         private readonly IRepository<ReadingPeriodSet> _readingPeriodSetRepository;
 | |
|         private readonly IRepository<ReadModule> _readModuleRepository;
 | |
| 
 | |
| 
 | |
|         public ReadModuleService(IRepository<SubjectVisit> subjectVisitRepository,
 | |
|             IRepository<Subject> subjectRepository,
 | |
|             IRepository<VisitStage> visitstageRepository,
 | |
|             IRepository<User> UserRepository,
 | |
|             IRepository<Trial> trialRepository,
 | |
|              IRepository<VisitTask> visitTaskRepository,
 | |
|             IRepository<ClinicalDataTrialSet> clinicalDataTrialSetRepository,
 | |
|             IRepository<ReadModuleView> readModuleViewRepository,
 | |
|             IRepository<DicomInstance> dicomInstanceRepository,
 | |
|             IRepository<NoneDicomStudyFile> noneDicomStudyFileRepository,
 | |
|             IRepository<ReadingPeriodSet> readingPeriodSetRepository,
 | |
|             IRepository<ReadModule> readModuleRepository
 | |
|           )
 | |
|         {
 | |
|             this._subjectVisitRepository = subjectVisitRepository;
 | |
|             this._subjectRepository = subjectRepository;
 | |
|             this._visitstageRepository = visitstageRepository;
 | |
|             this._userRepository = UserRepository;
 | |
|             this._trialRepository = trialRepository;
 | |
|             this._visitTaskRepository = visitTaskRepository;
 | |
|             this._clinicalDataTrialSetRepository = clinicalDataTrialSetRepository;
 | |
|             this._readModuleViewRepository = readModuleViewRepository;
 | |
|             this._dicomInstanceRepository = dicomInstanceRepository;
 | |
|             this._noneDicomStudyFileRepository = noneDicomStudyFileRepository;
 | |
|             this._readingPeriodSetRepository = readingPeriodSetRepository;
 | |
|             this._readModuleRepository = readModuleRepository;
 | |
|         }
 | |
| 
 | |
| 
 | |
|         /// <summary>
 | |
|         /// 获取读片计划列表  byZhouhang 
 | |
|         /// </summary>
 | |
|         /// <param name="dto"></param>
 | |
|         /// <returns></returns>
 | |
|         public async Task<(PageOutput<ReadPlanView>, object)> GetReadPlanList(GetReadModuleDto dto)
 | |
|         {
 | |
|             var subjectQuery = _subjectRepository
 | |
|                .WhereIf(dto.TrialId != null, x => x.TrialId == dto.TrialId)
 | |
|                .WhereIf(dto.SubjectId != null, x => x.Id == dto.SubjectId)
 | |
|                .WhereIf(dto.TrialSiteCode != null, x => x.TrialSite.TrialSiteCode == dto.TrialSiteCode)
 | |
|                .WhereIf(dto.SubjectCode != null, x => x.Code == dto.SubjectCode)
 | |
|              
 | |
|                
 | |
|                
 | |
|                .Select(x => new ReadPlanView
 | |
|               {
 | |
|                   TrialSiteCode = x.TrialSite.TrialSiteCode,
 | |
|                   SiteCode = x.TrialSite.TrialSiteCode,
 | |
|                   SiteId = x.SiteId,
 | |
|                   SubjectCode = x.Code,
 | |
|                   SubjectId = x.Id,
 | |
| 
 | |
|                   //Data = x.SubjectVisitList.OrderByDescending(y => y.VisitNum).Select(y => new GetReadModuleOutDto()
 | |
|                   //{
 | |
|                   //    Id = y.Id,  //id
 | |
|                   //    Name = y.VisitName,
 | |
|                   //    ModuleType = y.InPlan ? ModuleTypeEnum.InPlanSubjectVisit : ModuleTypeEnum.OutPlanSubjectVisit, // 模块类型
 | |
|                   //    IsUrgent = x.IsUrgent, // 是否加急
 | |
|                   //    SubjectVisitId = y.Id, // 访视ID
 | |
|                   //    SubjectVisitName = y.VisitName, //  访视名称
 | |
|                   //    Status = ReadingCommon.GetVisitSubmitStateEnum(y), // 状态
 | |
|                   //    CreateTime = y.CreateTime, // 创建时间
 | |
|                   //    SubjectCode = y.Subject.Code, // 受试者code
 | |
|                   //    TrialSiteCode = x.TrialSite.TrialSiteCode, // 中心Code
 | |
|                   //    VisitNum = y.VisitNum,
 | |
| 
 | |
|                   //    IsFinalVisit = y.IsFinalVisit, // 是否为末次评估
 | |
|                   //    OutPlanPreviousVisitId = y.OutPlanPreviousVisitId, // 上一访视
 | |
|                   //    OutPlanPreviousVisitName = y.OutPlanPreviousVisit.VisitName, // 上一访视名称
 | |
|                   //    SiteId = x.Site.Id,  // 中心ID
 | |
|                   //    IsVisit = true,  // 是否为访视
 | |
|                   //    PDState = y.PDState, // PD 进展
 | |
|                   //    IsEnrollmentConfirm = y.IsEnrollmentConfirm, // 入组
 | |
|                   //    SubjectId = x.Id,
 | |
|                   //}).ToList(),
 | |
| 
 | |
|                   //ReadModuleData = x.ReadModuleList.Select(
 | |
|                   // z => new GetReadModuleOutDto()
 | |
|                   // {
 | |
|                   //     CreateTime = z.CreateTime,
 | |
|                   //     Id = z.Id,
 | |
|                   //     Name = z.ModuleName,
 | |
|                   //     SubjectId = x.Id,
 | |
|                   //     ModuleType = z.ModuleType,
 | |
|                   //     Status = ReadingCommon.GetVisitSubmitStateEnum(z.SubjectVisit),
 | |
|                   //     SubjectCode = x.Code,
 | |
|                   //     TrialSiteCode = x.TrialSite.TrialSiteCode,
 | |
|                   //     SubjectVisitId = z.SubjectVisitId,
 | |
|                   //     SubjectVisitName = z.SubjectVisit.VisitName,  // 截止访视名称
 | |
|                   //     CutOffVisitId = z.SubjectVisitId,  // 截止访视
 | |
|                   //     CutOffVisitName = z.SubjectVisit.VisitName,  // 截止访视名称
 | |
|                   //     ReadModuleId = z.ReadModuleId,
 | |
|                   //     ReadModuleName = z.ReadModuleModel.ModuleName,
 | |
|                   //     IsUrgent = z.IsUrgent
 | |
|                   // }).ToList(),
 | |
| 
 | |
|               });
 | |
| 
 | |
|             var pageList = await subjectQuery.ToPagedListAsync(dto.PageIndex, dto.PageSize, dto.SortField == null || dto.SortField == string.Empty ? "SiteCode" : dto.SortField,
 | |
|                 dto.Asc);
 | |
| 
 | |
|             return (pageList, new
 | |
|             {
 | |
|                 MaxLength = pageList.CurrentPageData.ToList().Count()
 | |
|             });
 | |
|         }
 | |
| 
 | |
| 
 | |
| 
 | |
| 
 | |
| 
 | |
| 
 | |
|         /// <summary>
 | |
|         /// 获取读片模块
 | |
|         /// </summary>
 | |
|         [HttpPost]
 | |
|         public async Task<(PageOutput<GetReadModuleDtoOut>,object)> GetReadModuleList(GetReadModuleDto dto)
 | |
|         {
 | |
| 
 | |
|             #region MyRegion
 | |
|             dto.SortField = dto.SortField.IsNullOrEmpty() ? nameof(ReadModuleView.TrialSiteCode) : dto.SortField;
 | |
|             dto.SortField = dto.Asc ? dto.SortField : dto.SortField + " desc";
 | |
|            var subjectQuery = _readModuleViewRepository.WhereIf(dto.TrialId != null, x => x.TrialId == dto.TrialId)
 | |
|             .WhereIf(dto.SubjectId != null, x => x.SubjectId == dto.SubjectId)
 | |
|             .WhereIf(dto.TrialSiteCode != null && dto.TrialSiteCode != string.Empty, x => x.TrialSiteCode == dto.TrialSiteCode)
 | |
|             .WhereIf(dto.SubjectCode != null && dto.SubjectCode != string.Empty, x => x.SubjectCode == dto.SubjectCode)
 | |
|             .WhereIf(dto.ModuleType != null, x => x.ModuleType == dto.ModuleType)
 | |
|             .WhereIf(dto.ReadingStatus != null, x => x.ReadingStatus == dto.ReadingStatus)
 | |
|             .WhereIf(dto.Name != null, x => x.Name.Contains(dto.Name)).OrderBy(x => x.SiteCode);
 | |
| 
 | |
|             var subjectIds = await subjectQuery.OrderBy(dto.SortField).Select(x => x.SubjectId).Distinct().Skip((dto.PageIndex - 1) * dto.PageSize).Take(dto.PageSize).ToListAsync();
 | |
| 
 | |
|             List<ReadModuleView> ReadModuleViewList = await subjectQuery.Where(x => subjectIds.Contains(x.SubjectId)).OrderBy(dto.SortField).ToListAsync();
 | |
|             List<GetReadModuleDtoOut> getReadList = ReadModuleViewList.GroupBy(x => new { x.SubjectId, x.SiteId, x.TrialSiteCode, x.SubjectCode })
 | |
|                 .Select(x => new GetReadModuleDtoOut()
 | |
|                 {
 | |
|                     TrialSiteCode = x.Key.TrialSiteCode,
 | |
|                     SiteId = x.Key.SiteId,
 | |
|                     SubjectCode = x.Key.SubjectCode,
 | |
|                     SubjectId = x.Key.SubjectId,
 | |
|                     Data = x.OrderBy(x=>x.ModuleType).ThenBy(x=>x.VisitNum).ToList(),
 | |
|                 }).ToList();
 | |
|             PageOutput<GetReadModuleDtoOut> pageOutput = new PageOutput<GetReadModuleDtoOut>()
 | |
|             {
 | |
|                 PageSize = dto.PageSize,
 | |
|                 CurrentPageData = getReadList,
 | |
|                 PageIndex = dto.PageIndex,
 | |
|                 TotalCount = await subjectQuery.Select(x => x.SubjectId).Distinct().CountAsync(),
 | |
|             };
 | |
|             var maxcount = 0;
 | |
|             pageOutput.CurrentPageData.ForEach(x =>
 | |
|             {
 | |
|                 maxcount = maxcount < x.Data.Count ? x.Data.Count : maxcount;
 | |
|             });
 | |
|             var trialinfo = await _trialRepository.Where(x => x.Id == dto.TrialId).FirstNotNullAsync();
 | |
|             return (pageOutput, new
 | |
|             {
 | |
|                 MaxLength = maxcount,
 | |
|                 IsReadingTaskViewInOrder=trialinfo.IsReadingTaskViewInOrder,
 | |
|                 IsClinicalReading = trialinfo.IsClinicalReading,
 | |
|                 OnlyExistsMedicalHistory = !(await _clinicalDataTrialSetRepository.AnyAsync(x => x.TrialId == dto.TrialId && x.ClinicalDataSetName != "既往局部治疗史" && x.IsConfirm)),
 | |
|                 IsExistsSubjectClinicalData= await _clinicalDataTrialSetRepository.AnyAsync(x => x.TrialId == dto.TrialId&&x.ClinicalDataLevel== ClinicalLevel.Subject && x.IsConfirm),
 | |
|                 IsExistsVisitClinicalData = await _clinicalDataTrialSetRepository.AnyAsync(x => x.TrialId == dto.TrialId && x.ClinicalDataLevel == ClinicalLevel.SubjectVisit && x.IsConfirm),
 | |
|                 IsExistsReadingClinicalData = await _clinicalDataTrialSetRepository.AnyAsync(x => x.TrialId == dto.TrialId && x.ClinicalDataLevel == ClinicalLevel.Read && x.IsConfirm),
 | |
|             }) ;
 | |
| 
 | |
|             #endregion
 | |
|         }
 | |
| 
 | |
| 
 | |
| 
 | |
| 
 | |
|         ///// <summary>
 | |
|         ///// 访视阅片完成添加阅片期模块
 | |
|         ///// </summary>
 | |
|         ///// <returns></returns>
 | |
|         //public async Task<IResponseOutput> VisitFinishReadingAddReadModule(VisitFinishReadingAddReadModuleInDto inDto)
 | |
|         //{
 | |
|         //     var subjectVisit = await _subjectRepository.FirstOrDefaultNoTrackingAsync(x => x.Id == inDto.SubjectVisitId); 
 | |
|         //     List<ReadingPeriodSet> readingPeriodSets= _readingPeriodSetRepository.Where(x=>x.TrialId==inDto.TrialId&&x.IsTakeEffect=&&(x.ReadingScope==ReadingScopeEnum.All||(x.ReadingScope==ReadingScopeEnum.Site&&x.ReadingPeriodSites.Select(y=>y.SiteId).Contains(subjectVisit.SiteId))))
 | |
|         //}
 | |
| 
 | |
|         /// <summary>
 | |
|         /// 获取单条详情信息
 | |
|         /// </summary>
 | |
|         /// <param name="dto"></param>
 | |
|         /// <returns></returns>
 | |
|         [HttpPost]
 | |
|         public async Task<GetReadModuleSingleOutdto> GetReadModule(GetReadModuleSingleIndto dto)
 | |
|         {
 | |
|             var data = await GetReadModuleList(new GetReadModuleDto()
 | |
|             {
 | |
|                 SubjectId = dto.SubjectId,
 | |
|             });
 | |
| 
 | |
|             GetReadModuleSingleOutdto? readModule = data.Item1.CurrentPageData.FirstOrDefault().Data.Where(x => x.Id == dto.Id).Select(x => new GetReadModuleSingleOutdto()
 | |
|             {
 | |
|                 Id = x.Id,
 | |
|                 ModuleType = x.ModuleType,
 | |
|                 SubjectVisitId = x.SubjectVisitId,
 | |
|                 SubjectVisitName = x.SubjectVisitName,
 | |
|              
 | |
|                 Status = x.ReadingStatus,
 | |
|             }).FirstOrDefault();
 | |
| 
 | |
| 
 | |
|             var stakeholderIds = new List<Guid>();
 | |
| 
 | |
|             var subjectVisit =await _subjectVisitRepository.FirstOrDefaultAsync(x => x.Id == readModule.SubjectVisitId);
 | |
|             switch (readModule.Status)
 | |
|             {
 | |
|                 case ReadingStatusEnum.ImageNotSubmit:
 | |
|                     stakeholderIds.AddRange(await _dicomInstanceRepository.Where(x => x.SubjectVisitId == readModule.SubjectVisitId).Select(x => x.CreateUserId).Distinct().ToListAsync());
 | |
|                     stakeholderIds.AddRange(await _noneDicomStudyFileRepository.Where(x => x.NoneDicomStudy.SubjectVisitId == readModule.SubjectVisitId).Select(x => x.CreateUserId).Distinct().ToListAsync());
 | |
|                     break;
 | |
|                 case ReadingStatusEnum.ImageQuality:
 | |
|                     if (subjectVisit.PreliminaryAuditUserId != null)
 | |
|                     {
 | |
|                         stakeholderIds.Add(subjectVisit.PreliminaryAuditUserId.Value);
 | |
|                     }
 | |
|                     if (subjectVisit.ReviewAuditUserId != null)
 | |
|                     {
 | |
|                         stakeholderIds.Add(subjectVisit.ReviewAuditUserId.Value);
 | |
|                     }
 | |
|                     break;
 | |
|                 case ReadingStatusEnum.TaskAllocate:
 | |
|                     if (subjectVisit.CheckUserId != null)
 | |
|                     {
 | |
|                         stakeholderIds.Add(subjectVisit.CheckUserId.Value);
 | |
|                     }
 | |
|                     break;
 | |
|                 case ReadingStatusEnum.ImageReading:
 | |
| 
 | |
| 
 | |
|                     var doctorUserId = await _visitTaskRepository.Where(x => x.SouceReadModuleId == dto.Id || x.SourceSubjectVisitId == dto.Id)
 | |
|                         .Where(x => x.DoctorUserId != null).Select(x => x.DoctorUserId.Value).ToListAsync();
 | |
| 
 | |
|                     stakeholderIds.AddRange(doctorUserId);
 | |
|                   
 | |
|                     break;
 | |
|             };
 | |
| 
 | |
|             readModule.StakeholderIds = stakeholderIds.Distinct().ToList();
 | |
|             readModule.StakeholderNames = await _userRepository.Where(x => readModule.StakeholderIds.Contains(x.Id)).Select(x => x.FirstName + "/" + x.LastName).ToListAsync();
 | |
| 
 | |
|             return readModule;
 | |
|         }
 | |
| 
 | |
|         /// <summary>
 | |
|         /// 添加阅片的时候 获取访视
 | |
|         /// </summary>
 | |
|         /// <param name="inDto"></param>
 | |
|         /// <returns></returns>
 | |
|         public async Task<List<GetSubjectReadVisitsOutDto>> GetSubjectReadVisitList(GetSubjectReadVisitsInDto inDto)
 | |
|         {
 | |
|             var maxReadVisit = await _readModuleRepository.Where(x => x.SubjectId == inDto.SubjectId&&x.ReadingSetType==inDto.ReadingSetType).OrderByDescending(x=>x.VisitNum).FirstOrDefaultAsync();
 | |
|             var maxReadVisitNum= maxReadVisit==null?-1:maxReadVisit.VisitNum;
 | |
|             var visitQuery = _subjectVisitRepository.Where(x => x.SubjectId == inDto.SubjectId && x.LatestScanDate != null&&!x.IsLostVisit);
 | |
|             var finalVisitNum = await visitQuery.Where(x => x.IsFinalVisit).Select(x => x.VisitNum).FirstOrDefaultAsync();
 | |
| 
 | |
| 
 | |
|             var readModulequery = _readModuleRepository.AsQueryable();
 | |
|            var resultlist= await visitQuery.WhereIf(finalVisitNum != null&& finalVisitNum!=0, x => x.VisitNum <= finalVisitNum)
 | |
|                 .WhereIf(inDto.ReadingSetType== ReadingSetType.TumorReading, x => readModulequery.Where(y => y.SubjectVisitId == x.Id && y.ReadingSetType == ReadingSetType.ImageReading).Count() > 0)
 | |
|                 .Where(x=>x.VisitNum> maxReadVisitNum)
 | |
|                 
 | |
|                 .Where(x => readModulequery.Where(y => y.SubjectVisitId == x.Id && y.ReadingSetType == inDto.ReadingSetType).Count() == 0).OrderBy(x => finalVisitNum)
 | |
|                 .Select(x => new GetSubjectReadVisitsOutDto()
 | |
|                 {
 | |
|                     SubjectVisitId = x.Id,
 | |
|                     VisitName = x.VisitName,
 | |
|                     VisitNum = x.VisitNum,
 | |
|                 }).ToListAsync();
 | |
| 
 | |
|             return resultlist;
 | |
|         }
 | |
| 
 | |
|         /// <summary>
 | |
|         /// 添加阅片期
 | |
|         /// </summary>
 | |
|         /// <param name="dto"></param>
 | |
|         /// <returns></returns>
 | |
|         [HttpPost]
 | |
|         public async Task<IResponseOutput> AddReadModule(ReadModuleAddDto dto)
 | |
|         {
 | |
|             var visitQuery =  _subjectVisitRepository.Where(x => x.SubjectId == dto.SubjectId);
 | |
| 
 | |
|             visitQuery = visitQuery
 | |
|                 //.WhereIf(dto.ExpirationDate != null, x => x.LatestScanDate <= dto.ExpirationDate.Value)
 | |
|                 .WhereIf(dto.ExpirationVisitNum != null, x => x.VisitNum == dto.ExpirationVisitNum.Value);
 | |
|             var visit = visitQuery.OrderByDescending(x => x.VisitNum).FirstOrDefault();
 | |
| 
 | |
|             if (visit != null)
 | |
|             {
 | |
|                 await _readModuleRepository.AddAsync(new ReadModule()
 | |
|                 {
 | |
|                     Id= NewId.NextGuid(),
 | |
|                     SubjectId = dto.SubjectId,
 | |
|                     ModuleType = dto.ReadingSetType==ReadingSetType.ImageReading? ModuleTypeEnum.Global: ModuleTypeEnum.Oncology,
 | |
|                     IsUrgent = visit.IsUrgent,
 | |
|                     ModuleName = dto.Name,
 | |
|                     SubjectVisitId = visit.Id,
 | |
|                     ReadingSetType= dto.ReadingSetType,
 | |
|                     TrialId= dto.TrialId,
 | |
|                     VisitNum= visit.VisitNum,
 | |
|                     ReadingStatus = ReadingStatusEnum.TaskAllocate,
 | |
|                    
 | |
|                 });
 | |
|                 var res = await _readModuleRepository.SaveChangesAsync();
 | |
|                 return ResponseOutput.Ok(res);
 | |
|             }
 | |
|             else
 | |
|             {
 | |
|                 return ResponseOutput.NotOk("未找到符合要求的访视");
 | |
|             }
 | |
| 
 | |
|           
 | |
| 
 | |
|         }
 | |
| 
 | |
|         ///// <summary>
 | |
|         ///// 新增或者修改
 | |
|         ///// </summary>
 | |
|         ///// <param name="addOrEditReadModule"></param>
 | |
|         ///// <returns></returns>
 | |
|         //[HttpPost]
 | |
|         //public async Task<IResponseOutput> AddOrUpdateReadModuleService(ReadModuleAddOrEdit addOrEditReadModule)
 | |
|         //{
 | |
|         //    var entity = await _repository.InsertOrUpdateAsync<ReadModule, ReadModuleAddOrEdit>(addOrEditReadModule, true);
 | |
|         //    return ResponseOutput.Ok(entity.Id.ToString());
 | |
|         //}
 | |
| 
 | |
| 
 | |
| 
 | |
|         /// <summary>
 | |
|         /// 删除
 | |
|         /// </summary>
 | |
|         /// <param name="readModuleId"></param>
 | |
|         /// <returns></returns>
 | |
|         [HttpDelete("{readModuleId:guid}")]
 | |
|         public async Task<IResponseOutput> DeleteReadModule(Guid readModuleId)
 | |
|         {
 | |
|             await _readModuleRepository.DeleteFromQueryAsync(t => t.Id == readModuleId, true);
 | |
|             return ResponseOutput.Result(true);
 | |
|         }
 | |
| 
 | |
| 
 | |
|     }
 | |
| }
 |