EI-Image-Viewer-Api/IRaCIS.Core.Application/Service/Reading/ReadingPeriodSetService.cs

477 lines
23 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 IRaCIS.Core.Infra.EFCore.Common;
using IRaCIS.Core.Infrastructure.Extention;
using IRaCIS.Core.Application.Service;
using IRaCIS.Core.Application.ViewModel;
using IRaCIS.Core.Infrastructure;
namespace IRaCIS.Application.Services
{
/// <summary>
/// 阅片期配置
/// </summary>
[ApiExplorerSettings(GroupName = "Reading")]
public class ReadingPeriodSetService : BaseService
{
public IRepository<SubjectVisit> _subjectVisitRepository;
private readonly IRepository<ReadingPeriodSet> _readingPeriodSetRepository;
private readonly IRepository<ReadModule> _readModuleRepository;
private readonly IRepository<VisitStage> _visitStageRepository;
private readonly IRepository<Trial> _trialRepository;
private readonly IRepository<VisitTask> _visitTaskRepository;
private readonly IVisitTaskHelpeService _visitTaskHelpeService;
private readonly IRepository<ReadingPeriodPlan> _readingPeriodPlanRepository;
private readonly IRepository<Site> _siteSetRepository;
private readonly IRepository<Subject> _subjectRepository;
public ReadingPeriodSetService(IRepository<SubjectVisit> subjectVisitRepository,
IRepository<ReadingPeriodSet> ReadingPeriodSetRepository,
IRepository<ReadModule> readModuleRepository,
IRepository<VisitStage> visitStageRepository,
IRepository<Trial> trialRepository,
IRepository<VisitTask> visitTaskRepository,
IVisitTaskHelpeService visitTaskHelpeService,
IRepository<ReadingPeriodPlan> readingPeriodPlanRepository,
IRepository<Site> SiteSetRepository,
IRepository<Subject> subjectRepository
)
{
_subjectVisitRepository = subjectVisitRepository;
_readingPeriodSetRepository = ReadingPeriodSetRepository;
this._readModuleRepository = readModuleRepository;
this._visitStageRepository = visitStageRepository;
this._trialRepository = trialRepository;
this._visitTaskRepository = visitTaskRepository;
this._visitTaskHelpeService = visitTaskHelpeService;
this._readingPeriodPlanRepository = readingPeriodPlanRepository;
_siteSetRepository = SiteSetRepository;
_subjectRepository = subjectRepository;
}
/// <summary>
/// 新增或者修改
/// </summary>
/// <param name="addOrEditReadingPeriodSet"></param>
/// <returns></returns>
[HttpPost]
public async Task<IResponseOutput> AddOrUpdateReadingPeriodSet(ReadingPeriodSetAddOrEdit addOrEditReadingPeriodSet)
{
if (await _readingPeriodSetRepository.AnyAsync(x => x.Id != addOrEditReadingPeriodSet.Id&&x.IsTakeEffect!= ReadingPeriodStatus.Revocation && x.TrialId == addOrEditReadingPeriodSet.TrialId && x.ReadingPeriodName == addOrEditReadingPeriodSet.ReadingPeriodName))
{
return ResponseOutput.NotOk("阅片期名称重复,操作失败");
}
if (addOrEditReadingPeriodSet.ReadingPeriodName == "Global")
{
return ResponseOutput.NotOk("阅片期名称不能为Global");
}
if (addOrEditReadingPeriodSet.Id == null)
{
var entity = _mapper.Map<ReadingPeriodSet>(addOrEditReadingPeriodSet);
entity.ReadingPeriodSites = addOrEditReadingPeriodSet.SiteIds.Select(x => new ReadingPeriodSite()
{
ReadingPeriodSetId = entity.Id,
TrialId = entity.TrialId,
SiteId = x,
}).ToList();
entity.ReadingPeriodPlanList = addOrEditReadingPeriodSet.SubjectVisitIds.Select(x => new ReadingPeriodPlan
{
ReadingPeriodSetId = entity.Id,
SubjectVisitId = x,
}).ToList();
await _readingPeriodSetRepository.AddAsync(entity, true);
return ResponseOutput.Ok(entity.Id);
}
else
{
var entity = (await _readingPeriodSetRepository.Where(t => t.Id == addOrEditReadingPeriodSet.Id, true).Include(t => t.ReadingPeriodSites).Include(x => x.ReadingPeriodPlanList).FirstOrDefaultAsync()).IfNullThrowException();
_mapper.Map(addOrEditReadingPeriodSet, entity);
entity.ReadingPeriodSites = addOrEditReadingPeriodSet.SiteIds.Select(x => new ReadingPeriodSite()
{
ReadingPeriodSetId = entity.Id,
TrialId = entity.TrialId,
SiteId = x,
}).ToList();
entity.ReadingPeriodPlanList = addOrEditReadingPeriodSet.SubjectVisitIds.Select(x => new ReadingPeriodPlan
{
ReadingPeriodSetId = entity.Id,
SubjectVisitId = x,
}).ToList();
var success = await _readingPeriodSetRepository.SaveChangesAsync();
return ResponseOutput.Ok(entity.Id);
}
}
/// <summary>
/// 获取影像阅片的预览 // 需要清除之前已经选中的
/// </summary>
/// <returns></returns>
[HttpPost]
public async Task<PageOutput<PreviewTheReadingListOutDto>> GetPreviewTheReadingList(PreviewTheReadingListInDto inDto)
{
var readModulequery = _readModuleRepository.AsQueryable();
// 当前项目 最晚拍片日期不为null 中心筛选
var visitQuery = _subjectVisitRepository.Where(x => x.TrialId == inDto.TrialId &&x.LatestScanDate!=null&&!x.IsLostVisit)
.WhereIf(inDto.ReadingScope== ReadingScopeEnum.Site, x => inDto.SiteIds.Contains(x.SiteId));
// 已经存在的访视 需要排除
var existsBubjectVisitsQuery= _readModuleRepository.Where(y => y.ReadingSetType == inDto.ReadingSetType && y.TrialId == inDto.TrialId).Select(x => x.SubjectVisitId);
visitQuery = visitQuery.Where(x => !existsBubjectVisitsQuery.Contains(x.Id))
.WhereIf(inDto.ExpirationDate != null, x => x.LatestScanDate <= inDto.ExpirationDate.Value)
.WhereIf(inDto.ExpirationVisitNum != null, x => x.VisitNum == inDto.ExpirationVisitNum)
.WhereIf(inDto.ReadingSetType==ReadingSetType.TumorReading,x => readModulequery.Where(y => y.SubjectVisitId == x.Id && y.ReadingSetType == ReadingSetType.ImageReading).Count() > 0);
var subjectIdlist = await visitQuery.OrderBy(x => x.SubjectId).Select(x => x.SubjectId).Distinct().Skip((inDto.PageIndex - 1) * inDto.PageSize).Take(inDto.PageSize).ToListAsync();
var totalCount = visitQuery.Select(x => x.SubjectId).Distinct().Count();
var visitlist = await visitQuery.Include(x => x.Subject).Include(x => x.TrialSite).Where(x => subjectIdlist.Contains(x.SubjectId)).ToListAsync();
var subjectVisits = visitlist.GroupBy(x => x.SubjectId).Select(x => new
{
SubjectId = x.Key,
Visits = x.ToList()
});
List<SubjectVisit> visits = new List<SubjectVisit>();
subjectVisits.ForEach(x =>
{
var visit = x.Visits.OrderByDescending(x => x.VisitNum).FirstOrDefault();
if (visit != null)
{
visits.Add(visit);
}
});
PageOutput<PreviewTheReadingListOutDto> result = new PageOutput<PreviewTheReadingListOutDto>()
{
CurrentPageData = visits
.Select(x => new PreviewTheReadingListOutDto
{
ExpirationDate = inDto.ExpirationDate,
SubjectVisitId = x.Id,
TrialSiteCode = x.TrialSite.TrialSiteCode,
LatestScanDate = x.LatestScanDate,
ReadingPeriodName = inDto.ReadingPeriodName,
SubjectCode = x.Subject.Code,
SubjectId = x.SubjectId,
SubjectVisitName = x.VisitName,
}).ToList(),
PageSize = inDto.PageSize,
PageIndex = inDto.PageIndex,
TotalCount = totalCount,
};
return result;
}
/// <summary>
/// 添加对应的阅片
/// </summary>
/// <param name="inDto"></param>
/// <returns></returns>
public async Task<IResponseOutput> GenerateReadingTask(ReadingToGenerateInDto inDto)
{
List<ReadingPeriodPlan> plans = new List<ReadingPeriodPlan>();
inDto.SubjectVisitIds.ForEach(x =>
{
plans.Add(new ReadingPeriodPlan()
{
SubjectVisitId = x,
ReadingPeriodSetId = inDto.ReadingPeriodSetId
});
});
await _readingPeriodPlanRepository.DeleteFromQueryAsync(x => x.ReadingPeriodSetId == inDto.ReadingPeriodSetId);
await _readingPeriodPlanRepository.SaveChangesAsync();
await _readingPeriodPlanRepository.AddRangeAsync(plans);
var result = await _readingPeriodPlanRepository.SaveChangesAsync();
return ResponseOutput.Result(result);
}
/// <summary>
/// 获取选中的计划
/// </summary>
/// <param name="inDto"></param>
/// <returns></returns>
[HttpPost]
public async Task<PageOutput<PreviewTheReadingListOutDto>> GetPreviewTheReadingPlanList(PreviewTheReadingListDto inDto)
{
var plans = _readingPeriodPlanRepository.Where(x => x.ReadingPeriodSetId == inDto.ReadingPeriodSetId).Include(x => x.SubjectVisit).Include(x => x.SubjectVisit.TrialSite).Include(x => x.SubjectVisit.Subject)
.Include(x => x.ReadingPeriodSet).Select(x => new PreviewTheReadingListOutDto
{
Id = x.Id,
ExpirationDate = x.ReadingPeriodSet.ExpirationDate,
SubjectVisitId = x.SubjectVisitId,
TrialSiteCode = x.SubjectVisit.TrialSite.TrialSiteCode,
LatestScanDate = x.SubjectVisit.LatestScanDate,
ReadingPeriodName = x.ReadingPeriodSet.ReadingPeriodName,
ReadingPeriodSetId = x.ReadingPeriodSetId,
SubjectCode = x.SubjectVisit.Subject.Code,
SubjectId = x.SubjectVisit.SubjectId,
SubjectVisitName = x.SubjectVisit.VisitName,
EffectOfTime = x.ReadingPeriodSet.EffectOfTime,
});
return await plans.ToPagedListAsync(inDto.PageIndex, inDto.PageSize, inDto.SortField == null ? nameof(PreviewTheReadingListOutDto.SubjectId) : inDto.SortField,
inDto.Asc);
}
/// <summary>
/// 分页获取
/// </summary>
/// <param name="query"></param>
/// <returns></returns>
[HttpPost]
public async Task<PageOutput<ReadingPeriodSetView>> GetReadingPeriodSetList(ReadingPeriodSetQuery query)
{
var readQuery =_readingPeriodSetRepository.Where(t=>t.TrialId==query.TrialId).Include(x=>x.ReadingPeriodSites)
.WhereIf(query.ReadingPeriodName != null, x => x.ReadingPeriodName.Contains(query.ReadingPeriodName!))
.ProjectTo<ReadingPeriodSetView>(_mapper.ConfigurationProvider);
var pageList= await readQuery.ToPagedListAsync(query.PageIndex, query.PageSize, query.SortField == null ? nameof(ReadingPeriodSetView.CreateTime) : query.SortField,
query.Asc);
pageList.CurrentPageData.ForEach(x =>
{
x.SubjectVisitName = x.IsGlobal ? "末次访视" : x.SubjectVisitName;
});
return pageList;
}
/// <summary>
/// 获取单条
/// </summary>
/// <param name="id"></param>
/// <returns></returns>
[HttpPost("{id:guid}")]
public async Task<ReadingPeriodSetView> GetReadingPeriodSet(Guid id)
{
return await _readingPeriodSetRepository.AsQueryable().Include(x => x.ReadingPeriodSites).Where(x => x.Id == id).ProjectTo<ReadingPeriodSetView>(_mapper.ConfigurationProvider).FirstOrDefaultAsync();
}
/// <summary>
/// 获取阅片期配置的截至访视的下拉框
/// </summary>
/// <param name="inDto"></param>
/// <returns></returns>
[HttpPost]
public async Task<List<GetReadingVisitListOutDto>> GetReadingVisitList(GetReadingVisitListInDto inDto)
{
var maxVisitNum = await _readingPeriodSetRepository.Where(x => x.TrialId == inDto.TrialId && x.ReadingSetType == inDto.ReadingSetType&&x.IsTakeEffect== ReadingPeriodStatus.TakeEffect).MaxAsync(x => x.ExpirationVisitNum)??0;
var thisVisitNum = await _readingPeriodSetRepository.Where(x => x.Id == inDto.ReadingPeriodSetId).Select(x => x.ExpirationVisitNum).FirstOrDefaultAsync() ?? -1;
var globalVisitNum = new List<decimal>();
if (inDto.ReadingSetType == ReadingSetType.TumorReading)
{
globalVisitNum = await _readModuleRepository.Where(x => x.ReadingSetType == ReadingSetType.ImageReading && x.TrialId == inDto.TrialId).Select(x => x.VisitNum).Distinct().ToListAsync();
}
List <GetReadingVisitListOutDto> result = await _visitStageRepository.Where(x => x.TrialId == inDto.TrialId )
.WhereIf(inDto.ReadingSetType == ReadingSetType.TumorReading,x=> globalVisitNum.Contains(x.VisitNum))
.Where(x=>x.VisitNum== thisVisitNum || x.VisitNum >= maxVisitNum).Select(x => new GetReadingVisitListOutDto()
{
VisitName = x.VisitName,
VisitNum = x.VisitNum,
VisitStageId = x.Id,
}).ToListAsync();
return result;
}
/// <summary>
/// 设置阅片期配置是否生效
/// </summary>
/// <param name="indto"></param>
/// <returns></returns>
[HttpPut]
public async Task<IResponseOutput> SetReadingPeriodSetEffect(SetReadingPeriodSetEffect indto)
{
if (indto.IsTakeEffect == ReadingPeriodStatus.TakeEffect)
{
var readingPeriodSet = await _readingPeriodSetRepository.Where(x => x.Id == indto.Id).FirstNotNullAsync();
var plans = _readingPeriodPlanRepository.Where(x => x.ReadingPeriodSetId == indto.Id).Include(x => x.SubjectVisit)
.Include(x => x.ReadingPeriodSet).Include(x => x.SubjectVisit).ToList();
var needAddVisitIds = plans.Select(x => x.SubjectVisitId).ToList();
var repeatVisitNames = _readModuleRepository.Where(x => x.ReadingSetType == readingPeriodSet.ReadingSetType && needAddVisitIds.Contains(x.SubjectVisitId)).Select(x =>x.Subject.Code+"的"+ x.SubjectVisit.VisitName).ToList();
if(repeatVisitNames.Count!=0)
{
return ResponseOutput.NotOk($"{string.Join(",", repeatVisitNames)}已经添加过阅片期,无法设置生效");
}
List<ReadModule> readModules = new List<ReadModule>();
foreach (var item in plans)
{
readModules.Add(new ReadModule()
{
Id = NewId.NextGuid(),
SubjectId = item.SubjectVisit.SubjectId,
ModuleType = item.ReadingPeriodSet.ReadingSetType == ReadingSetType.ImageReading ? ModuleTypeEnum.Global : ModuleTypeEnum.Oncology,
IsUrgent = item.SubjectVisit.IsUrgent,
ModuleName = item.ReadingPeriodSet.ReadingPeriodName,
SubjectVisitId = item.SubjectVisitId,
ReadingSetType = item.ReadingPeriodSet.ReadingSetType,
ReadingPeriodSetId = item.ReadingPeriodSet.Id,
ReadingStatus = ReadingStatusEnum.TaskAllocate,
TrialId = readingPeriodSet.TrialId,
VisitNum = item.SubjectVisit.VisitNum,
});
};
// 判断是否要添加肿瘤学或者全局阅片任务
var subjectVisitIds = readModules.Select(x => x.SubjectVisitId).ToList();
switch (readingPeriodSet.ReadingSetType)
{
case ReadingSetType.ImageReading:
var taskInfoList = await _visitTaskRepository.Where(x => subjectVisitIds.Contains(x.SourceSubjectVisitId ?? default(Guid))&&x.TaskState==TaskState.Effect && x.ReadingTaskState == ReadingTaskState.HaveSigned&&!x.IsAnalysisCreate).ToListAsync();
foreach (var item in taskInfoList)
{
var readModule = readModules.Where(x => x.SubjectVisitId == item.SourceSubjectVisitId).FirstOrDefault();
if (readModule != null)
{
await _visitTaskHelpeService.AddTaskAsync(new GenerateTaskCommand()
{
OriginalVisitId = item.Id,
ReadingCategory = GenerateTaskCategory.Global,
TrialId = item.TrialId,
ReadingGenerataTaskList = new List<ReadingGenerataTaskDTO>() {
new ReadingGenerataTaskDTO()
{
IsUrgent = readModule.IsUrgent??false,
SubjectId = readModule.SubjectId,
VisitNum=readModule.VisitNum,
ReadingName = readModule.ModuleName,
ReadModuleId =readModule.Id,
ReadingCategory = ReadingCategory.Global,
}
}
});
}
}
break;
case ReadingSetType.TumorReading:
var trialInfo = await _trialRepository.Where(x => x.Id == readingPeriodSet.TrialId).FirstNotNullAsync();
var globalModuleIds = await _readModuleRepository.Where(x => subjectVisitIds.Contains(x.SubjectVisitId) && x.ModuleType == ModuleTypeEnum.Global).Select(x => x.Id).ToListAsync();
var globalTaskInfo = await _visitTaskRepository.Where(x => globalModuleIds.Contains(x.SouceReadModuleId ?? default(Guid)) && x.TaskState == TaskState.Effect && x.ReadingTaskState == ReadingTaskState.HaveSigned&&!x.IsAnalysisCreate).GroupBy(x=> new { x.SouceReadModuleId }).Select(x =>
new {
SouceReadModuleId=x.Key.SouceReadModuleId,
Count=x.ToList().Count,
TaskId = x.Select(x=>x.Id).FirstOrDefault(),
ReadModuleId = x.Select(x => x.SouceReadModuleId).FirstOrDefault(),
JudgeTaskId = x.Select(x => x.JudgeVisitTaskId).FirstOrDefault(),
JudgeTaskResultId = x.Select(x => x.JudgeVisitTask.JudgeResultTaskId).FirstOrDefault(),
}).ToListAsync();
foreach (var item in globalTaskInfo)
{
if (item.Count == (int)trialInfo.ReadingType)
{
if (item.JudgeTaskId == null || item.JudgeTaskResultId != null)
{
var readModule = readModules.Where(x => x.Id == item.ReadModuleId).FirstOrDefault();
await _visitTaskHelpeService.AddTaskAsync(new GenerateTaskCommand()
{
OriginalVisitId = item.TaskId,
ReadingCategory = GenerateTaskCategory.Oncology,
TrialId = readingPeriodSet.TrialId,
ReadingGenerataTaskList = new List<ReadingGenerataTaskDTO>() {
new ReadingGenerataTaskDTO()
{
IsUrgent = readModule.IsUrgent ?? false,
SubjectId = readModule.SubjectId,
VisitNum=readModule.VisitNum,
ReadingName = readModule.ModuleName,
ReadModuleId =readModule.Id,
ReadingCategory = ReadingCategory.Oncology,
}
}
});
}
}
}
break;
}
await _readModuleRepository.AddRangeAsync(readModules);
}
else
{
List<Guid> readModuleIds = await _readModuleRepository.Where(x => x.ReadingPeriodSetId == indto.Id).Select(x => x.Id).ToListAsync();
if (await _visitTaskRepository.AnyAsync(x => readModuleIds.Contains(x.SouceReadModuleId ?? default(Guid)) && x.ReadingTaskState == ReadingTaskState.HaveSigned && x.TaskState == TaskState.Effect))
{
throw new BusinessValidationFailedException("当前阅片已生成任务并且阅片完成,撤销失败。");
}
await _visitTaskRepository.BatchUpdateNoTrackingAsync(x => readModuleIds.Contains(x.SouceReadModuleId ?? default(Guid)), x => new VisitTask()
{
TaskState = TaskState.Adbandon
});
await _readModuleRepository.DeleteFromQueryAsync(x => x.ReadingPeriodSetId == indto.Id);
}
var readQuery = await _readingPeriodSetRepository.UpdatePartialFromQueryAsync(indto.Id, x => new ReadingPeriodSet()
{
IsTakeEffect = indto.IsTakeEffect,
EffectOfTime = indto.IsTakeEffect == ReadingPeriodStatus.TakeEffect ? DateTime.Now : null,
});
var result = await _readingPeriodSetRepository.SaveChangesAsync();
return ResponseOutput.Result(result);
}
/// <summary>
/// 删除
/// </summary>
/// <param name="readingPeriodSetId"></param>
/// <returns></returns>
[HttpDelete("{readingPeriodSetId:guid}")]
public async Task<IResponseOutput> DeleteReadingPeriodSet(Guid readingPeriodSetId)
{
var success = await _repository.BatchDeleteAsync<ReadingPeriodSet>(t => t.Id == readingPeriodSetId);
return ResponseOutput.Result(success);
}
}
}