diff --git a/IRaCIS.Core.API/Controllers/UploadDownLoadController.cs b/IRaCIS.Core.API/Controllers/UploadDownLoadController.cs index 0a79b00c3..f837d9c4c 100644 --- a/IRaCIS.Core.API/Controllers/UploadDownLoadController.cs +++ b/IRaCIS.Core.API/Controllers/UploadDownLoadController.cs @@ -239,7 +239,7 @@ namespace IRaCIS.Core.API.Controllers { - _logger.LogError("请求到达接口"); + //_logger.LogError("请求到达接口"); // validation of Content-Type // 1. first, it must be a form-data request diff --git a/IRaCIS.Core.Application/IRaCIS.Core.Application.xml b/IRaCIS.Core.Application/IRaCIS.Core.Application.xml index 9ca922c64..241e56c3c 100644 --- a/IRaCIS.Core.Application/IRaCIS.Core.Application.xml +++ b/IRaCIS.Core.Application/IRaCIS.Core.Application.xml @@ -7646,6 +7646,11 @@ 处理拍片日期 + + + 因为可能先一致性核查通过,生成其他标准的任务了,新签名的标准也需要产生任务 + + 构造函数注入 diff --git a/IRaCIS.Core.Application/Service/Allocation/DTO/TaskAllocationRuleViewModel.cs b/IRaCIS.Core.Application/Service/Allocation/DTO/TaskAllocationRuleViewModel.cs index a0d82917b..c926c4090 100644 --- a/IRaCIS.Core.Application/Service/Allocation/DTO/TaskAllocationRuleViewModel.cs +++ b/IRaCIS.Core.Application/Service/Allocation/DTO/TaskAllocationRuleViewModel.cs @@ -208,6 +208,15 @@ namespace IRaCIS.Core.Application.ViewModel public class GenerateTaskCommand { public Guid TrialId { get; set; } + + //针对访视产生任务的 有用 + public bool IsAssignSubjectToDoctor { get; set; } + + //访视任务产生的时候传递 + + public List VisitGenerataTaskList { get; set; } = new List(); + + public GenerateTaskCategory ReadingCategory { get; set; } @@ -216,13 +225,6 @@ namespace IRaCIS.Core.Application.ViewModel /// public Guid OriginalVisitId { get; set; } - //针对访视产生任务的 有用 - public bool IsAssignSubjectToDoctor { get; set; } - - //访视任务产生的时候传递 - - public List VisitGenerataTaskList { get; set; } = new List(); - //裁判的时候传递 public List JudgeVisitTaskIdList { get; set; } = new List(); @@ -237,7 +239,6 @@ namespace IRaCIS.Core.Application.ViewModel public Action Action; - //public ReReadingApplyGenerateTaskCommand ReReadingApplyGenerateTaskCommand { get; set; } = new ReReadingApplyGenerateTaskCommand(); //自身一致性 public List GenerataConsistentTaskList { get; set; } diff --git a/IRaCIS.Core.Application/Service/Allocation/Interface/IVisitTaskHelpeService.cs b/IRaCIS.Core.Application/Service/Allocation/Interface/IVisitTaskHelpeService.cs index 73e891112..ac847dc70 100644 --- a/IRaCIS.Core.Application/Service/Allocation/Interface/IVisitTaskHelpeService.cs +++ b/IRaCIS.Core.Application/Service/Allocation/Interface/IVisitTaskHelpeService.cs @@ -14,5 +14,7 @@ namespace IRaCIS.Core.Application.Service Task GenerateVisitTaskAsync(Guid trialId, List subjectVisitIdList, bool isAssignSubjectToDoctor = false); Task AddTaskAsync(GenerateTaskCommand generateTaskCommand); + + Task BaseCritrionGenerateVisitTask(Guid trialId, Guid confirmedTrialReadingCriterionId); } } \ No newline at end of file diff --git a/IRaCIS.Core.Application/Service/Allocation/VisitTaskHelpeService.cs b/IRaCIS.Core.Application/Service/Allocation/VisitTaskHelpeService.cs index db27f8f30..d620206f7 100644 --- a/IRaCIS.Core.Application/Service/Allocation/VisitTaskHelpeService.cs +++ b/IRaCIS.Core.Application/Service/Allocation/VisitTaskHelpeService.cs @@ -80,13 +80,153 @@ namespace IRaCIS.Core.Application.Service + public async Task BaseCritrionGenerateVisitTask(Guid trialId, Guid confirmedTrialReadingCriterionId) + { + + var needGenerateVisit = await _subjectVisitRepository.Where(t => t.TrialId == trialId && t.CheckState == CheckStateEnum.CVPassed && + !t.VisitTaskList.Any(u=>u.TrialReadingCriterionId== confirmedTrialReadingCriterionId &&u.SourceSubjectVisitId==t.Id)).ToListAsync(); + + + var trialReadingCriterionConfig = await _trialReadingCriterionRepository.Where(t => t.Id == confirmedTrialReadingCriterionId).Select(t => new { TrialReadingCriterionId = t.Id, t.ReadingTool, t.ReadingType, t.IsReadingTaskViewInOrder, t.IsFollowVisitAutoAssign, t.IsFollowGlobalVisitAutoAssign, t.FollowGlobalVisitAutoAssignDefaultState, t.FollowVisitAutoAssignDefaultState, t.TaskAllocateObjEnum }).FirstOrDefaultAsync(); + + + var dbMaxCode = _visitTaskRepository.Where(t => t.TrialId == trialId).Select(t => t.Code).DefaultIfEmpty().Max(); + + var cacheMaxCodeInt = _provider.Get($"{trialId}_{StaticData.CacheKey.TaskMaxCode}").Value; + + int currentMaxCodeInt = cacheMaxCodeInt > dbMaxCode ? cacheMaxCodeInt : dbMaxCode; + + + foreach (var subjectVisit in needGenerateVisit) + { + var assignConfigList = await _subjectUserRepository.Where(t => t.TrialId == trialId && t.TrialReadingCriterionId == trialReadingCriterionConfig.TrialReadingCriterionId && t.SubjectId == subjectVisit.SubjectId && t.OrignalSubjectUserId == null && t.IsConfirmed).Select(u => new { u.DoctorUserId, u.ArmEnum }).ToListAsync(); + + + if (trialReadingCriterionConfig.ReadingType == ReadingMethod.Double) + { + //每个访视 根据项目配置生成任务 双审生成两个 + var task1 = await _visitTaskRepository.AddAsync(new VisitTask() + { + TrialId = trialId, + SubjectId = subjectVisit.SubjectId, + IsUrgent = subjectVisit.IsUrgent, + TaskBlindName = subjectVisit.BlindName, + TaskName = subjectVisit.VisitName, + VisitTaskNum = subjectVisit.VisitNum, + //CheckPassedTime = subjectVisit.CheckPassedTime, + ArmEnum = Arm.DoubleReadingArm1,//特殊 + Code = currentMaxCodeInt + 1, + SourceSubjectVisitId = subjectVisit.Id, + TaskCode = AppSettings.GetCodeStr(currentMaxCodeInt + 1, nameof(VisitTask)), + ReadingCategory = ReadingCategory.Visit, + + TrialReadingCriterionId = trialReadingCriterionConfig.TrialReadingCriterionId + }); + + var task2 = await _visitTaskRepository.AddAsync(new VisitTask() + { + TrialId = trialId, + SubjectId = subjectVisit.SubjectId, + IsUrgent = subjectVisit.IsUrgent, + TaskBlindName = subjectVisit.BlindName, + TaskName = subjectVisit.VisitName, + VisitTaskNum = subjectVisit.VisitNum, + //CheckPassedTime = subjectVisit.CheckPassedTime, + ArmEnum = Arm.DoubleReadingArm2,//特殊 + Code = currentMaxCodeInt + 2, + SourceSubjectVisitId = subjectVisit.Id, + TaskCode = AppSettings.GetCodeStr(currentMaxCodeInt + 2, nameof(VisitTask)), + ReadingCategory = ReadingCategory.Visit, + + TrialReadingCriterionId = trialReadingCriterionConfig.TrialReadingCriterionId + }); + + currentMaxCodeInt = currentMaxCodeInt + 2; + + _provider.Set($"{trialId}_{StaticData.CacheKey.TaskMaxCode}", currentMaxCodeInt, TimeSpan.FromMinutes(30)); + + + + + var defaultState = trialReadingCriterionConfig.FollowVisitAutoAssignDefaultState == TaskAllocateDefaultState.InitAllocated ? TaskAllocationState.InitAllocated : TaskAllocationState.Allocated; + + if (assignConfigList.Any(t => t.ArmEnum == Arm.DoubleReadingArm1)) + { + task1.TaskAllocationState = defaultState; + //分配给对应Arm的人 + task1.DoctorUserId = assignConfigList.FirstOrDefault(t => t.ArmEnum == Arm.DoubleReadingArm1).DoctorUserId; + task1.AllocateTime = DateTime.Now; + + task1.SuggesteFinishedTime = DateTime.Now.AddDays(7); + } + + if (assignConfigList.Any(t => t.ArmEnum == Arm.DoubleReadingArm2)) + { + task2.TaskAllocationState = defaultState; + task2.DoctorUserId = assignConfigList.FirstOrDefault(t => t.ArmEnum == Arm.DoubleReadingArm2).DoctorUserId; + task2.AllocateTime = DateTime.Now; + task2.SuggesteFinishedTime = DateTime.Now.AddDays(7); + } + + } + else if (trialReadingCriterionConfig.ReadingType == ReadingMethod.Single) + { + + + var singleTask = await _visitTaskRepository.AddAsync(new VisitTask() + { + TrialId = trialId, + SubjectId = subjectVisit.SubjectId, + IsUrgent = subjectVisit.IsUrgent, + TaskBlindName = subjectVisit.BlindName, + TaskName = subjectVisit.VisitName, + VisitTaskNum = subjectVisit.VisitNum, + //CheckPassedTime = subjectVisit.CheckPassedTime, + ArmEnum = Arm.SingleReadingArm, //特殊 + Code = currentMaxCodeInt + 1, + SourceSubjectVisitId = subjectVisit.Id, + TaskCode = AppSettings.GetCodeStr(currentMaxCodeInt + 1, nameof(VisitTask)), + ReadingCategory = ReadingCategory.Visit, + TrialReadingCriterionId = trialReadingCriterionConfig.TrialReadingCriterionId + }); + + + currentMaxCodeInt = currentMaxCodeInt + 1; + + _provider.Set($"{trialId}_{StaticData.CacheKey.TaskMaxCode}", currentMaxCodeInt, TimeSpan.FromMinutes(30)); + + + + var defaultState = trialReadingCriterionConfig.FollowVisitAutoAssignDefaultState == TaskAllocateDefaultState.InitAllocated ? TaskAllocationState.InitAllocated : TaskAllocationState.Allocated; + + singleTask.TaskAllocationState = defaultState; + + singleTask.DoctorUserId = assignConfigList.FirstOrDefault(t => t.ArmEnum == 0).DoctorUserId; + + singleTask.AllocateTime = DateTime.Now; + + singleTask.SuggesteFinishedTime = DateTime.Now.AddDays(7); + + + } + await _visitTaskRepository.SaveChangesAsync(); + + } + + } + + + + + + public async Task AddTaskAsync(GenerateTaskCommand generateTaskCommand) { var trialId = generateTaskCommand.TrialId; var isAssignSubjectToDoctor = generateTaskCommand.IsAssignSubjectToDoctor; - var trialReadingCriterionConfigList = _trialReadingCriterionRepository.Where(t => t.TrialId == trialId && t.IsConfirm).Select(t => new { TrialReadingCriterionId= t.Id ,t.ReadingTool,t.ReadingType, t.IsReadingTaskViewInOrder, t.IsFollowVisitAutoAssign, t.IsFollowGlobalVisitAutoAssign, t.FollowGlobalVisitAutoAssignDefaultState, t.FollowVisitAutoAssignDefaultState,t.TaskAllocateObjEnum } ).ToList(); + var trialReadingCriterionConfigList = _trialReadingCriterionRepository.Where(t => t.TrialId == trialId && t.ReadingInfoSignTime !=null).Select(t => new { TrialReadingCriterionId= t.Id ,t.ReadingTool,t.ReadingType, t.IsReadingTaskViewInOrder, t.IsFollowVisitAutoAssign, t.IsFollowGlobalVisitAutoAssign, t.FollowGlobalVisitAutoAssignDefaultState, t.FollowVisitAutoAssignDefaultState,t.TaskAllocateObjEnum } ).ToList(); //var trialConfig = (await _trialRepository.Where(t => t.Id == trialId).Select(t => new { TrialId = t.Id, t.IsFollowVisitAutoAssign, t.IsFollowGlobalVisitAutoAssign, t.FollowGlobalVisitAutoAssignDefaultState, t.FollowVisitAutoAssignDefaultState, t.TaskAllocateObjEnum, }).FirstOrDefaultAsync()).IfNullThrowException(); @@ -589,21 +729,7 @@ namespace IRaCIS.Core.Application.Service var reReadingVisitTask = generateTaskCommand.ReReadingTask; - //foreach (var reReadingVisitTask in generateTaskCommand.ReReadingTaskList) - //{ - //reReadingVisitTask.OriginalReReadingId = reReadingVisitTask.Id; - //reReadingVisitTask.Id = Guid.Empty; - //reReadingVisitTask.SignTime = null; - //reReadingVisitTask.AllocateTime = null; - //reReadingVisitTask.RequestReReadingReason = generateTaskCommand.ReReadingApplyGenerateTaskCommand.RequestReReadingReason; - //reReadingVisitTask.RequestReReadingType = generateTaskCommand.ReReadingApplyGenerateTaskCommand.RequestReReadingType; - //reReadingVisitTask.RequestReReadingUserId = _userInfo.Id; - - //reReadingVisitTask.Code = currentMaxCodeInt + 1; - //reReadingVisitTask.TaskCode = AppSettings.GetCodeStr(currentMaxCodeInt + 1, nameof(VisitTask)); - - // await _visitTaskRepository.AddAsync(reReadingVisitTask); var newTask = await _visitTaskRepository.AddAsync(new VisitTask() @@ -663,7 +789,6 @@ namespace IRaCIS.Core.Application.Service }); } - //await _visitTaskReReadingRepository.BatchUpdateNoTrackingAsync(t=>t.) //是否增加任务类别 diff --git a/IRaCIS.Core.Application/Service/ImageAndDoc/DicomArchiveService.cs b/IRaCIS.Core.Application/Service/ImageAndDoc/DicomArchiveService.cs index 8492fb466..18a035d65 100644 --- a/IRaCIS.Core.Application/Service/ImageAndDoc/DicomArchiveService.cs +++ b/IRaCIS.Core.Application/Service/ImageAndDoc/DicomArchiveService.cs @@ -3,7 +3,6 @@ using Dicom.Imaging.Codec; using EasyCaching.Core; using IRaCIS.Core.Application.Contracts.Dicom; using IRaCIS.Core.Domain.Share; -using Microsoft.Extensions.Hosting; using System.Text; using IRaCIS.Core.Application.Contracts; using IRaCIS.Core.Application.Helper; @@ -17,7 +16,7 @@ namespace IRaCIS.Core.Application.Services private readonly IRepository _studyRepository; private readonly IRepository _seriesRepository; private readonly IRepository _instanceRepository; - private readonly IRepository _inspectionService; + private readonly IRepository _dictionaryRepository; private readonly IEasyCachingProvider _provider; private readonly IWebHostEnvironment _hostEnvironment; @@ -28,7 +27,7 @@ namespace IRaCIS.Core.Application.Services IRepository seriesRepository, IRepository instanceRepository, IWebHostEnvironment hostEnvironment, - IRepository inspectionService, + IRepository dictionaryRepository, IEasyCachingProvider provider) { _hostEnvironment = hostEnvironment; @@ -37,7 +36,7 @@ namespace IRaCIS.Core.Application.Services _seriesRepository = seriesRepository; _instanceRepository = instanceRepository; - this._inspectionService = inspectionService; + _dictionaryRepository = dictionaryRepository; _provider = provider; } @@ -173,7 +172,7 @@ namespace IRaCIS.Core.Application.Services } - private DicomStudy CreateDicomStudy(DicomDataset dataset, DicomTrialSiteSubjectInfo addtionalInfo, out bool isStudyNeedAdd) + private DicomStudy CreateDicomStudy(DicomDataset dataset, DicomTrialSiteSubjectInfo addtionalInfo, out bool isStudyNeedAdd) { string studyInstanceUid = dataset.GetString(DicomTag.StudyInstanceUID); @@ -199,13 +198,18 @@ namespace IRaCIS.Core.Application.Services //dataset.GetSingleValue(DicomTag.StudyDate) + dataset.GetSingleValue(DicomTag.StudyTime) + var modality = dataset.GetSingleValueOrDefault(DicomTag.Modality, string.Empty); + + var dicModalityList = _dictionaryRepository.Where(t => t.Code == "Modality").SelectMany(t => t.ChildList.Select(c => c.Value)).ToList(); + dicomStudy = new DicomStudy { Id = studyId, StudyInstanceUid = studyInstanceUid, /* StudyTime = dataset.GetSingleValueOrDefault(DicomTag.StudyDate, DateTime.Now).Add(dataset.GetSingleValueOrDefault(DicomTag.StudyTime, DateTime.Now).TimeOfDay),*///dataset.GetDateTime(DicomTag.StudyDate, DicomTag.StudyTime), - StudyTime = dataset.GetSingleValueOrDefault(DicomTag.StudyDate,string.Empty)==string.Empty?null: dataset.GetSingleValue(DicomTag.StudyDate).Add(dataset.GetSingleValueOrDefault(DicomTag.StudyTime, string.Empty) == string.Empty ?TimeSpan.Zero: dataset.GetSingleValue(DicomTag.StudyTime).TimeOfDay) , - Modalities = dataset.GetSingleValueOrDefault(DicomTag.Modality, string.Empty), + StudyTime = dataset.GetSingleValueOrDefault(DicomTag.StudyDate, string.Empty) == string.Empty ? null : dataset.GetSingleValue(DicomTag.StudyDate).Add(dataset.GetSingleValueOrDefault(DicomTag.StudyTime, string.Empty) == string.Empty ? TimeSpan.Zero : dataset.GetSingleValue(DicomTag.StudyTime).TimeOfDay), + Modalities = modality, + ModalityForEdit = dicModalityList.Contains(modality) ? modality : String.Empty, Description = dataset.GetSingleValueOrDefault(DicomTag.StudyDescription, string.Empty), InstitutionName = dataset.GetSingleValueOrDefault(DicomTag.InstitutionName, string.Empty), PatientId = dataset.GetSingleValueOrDefault(DicomTag.PatientID, string.Empty), diff --git a/IRaCIS.Core.Application/Service/QC/DTO/QARecordViewModel.cs b/IRaCIS.Core.Application/Service/QC/DTO/QARecordViewModel.cs index 45bac0d84..5ef295020 100644 --- a/IRaCIS.Core.Application/Service/QC/DTO/QARecordViewModel.cs +++ b/IRaCIS.Core.Application/Service/QC/DTO/QARecordViewModel.cs @@ -378,7 +378,7 @@ namespace IRaCIS.Core.Application.Contracts.DTO public string BodyPartForEdit { get; set; } = String.Empty; - + public string ModalityForEdit { get; set; } = string.Empty; //public string PatientName { get; set; } = string.Empty; //public string PatientAge { get; set; } = string.Empty; diff --git a/IRaCIS.Core.Application/Service/QC/QCOperationService.cs b/IRaCIS.Core.Application/Service/QC/QCOperationService.cs index 897c74f57..b95c484f8 100644 --- a/IRaCIS.Core.Application/Service/QC/QCOperationService.cs +++ b/IRaCIS.Core.Application/Service/QC/QCOperationService.cs @@ -677,7 +677,8 @@ namespace IRaCIS.Core.Application.Image.QA study.BodyPartForEdit = updateModalityCommand.BodyPart; - study.Modalities = updateModalityCommand.Modality; + //study.Modalities = updateModalityCommand.Modality; + study.ModalityForEdit = updateModalityCommand.Modality; await _repository.BatchUpdateAsync(t => t.StudyId == studyId, r => new DicomSeries() { BodyPartForEdit = updateModalityCommand.BodyPart, Modality = updateModalityCommand.Modality }); } else if (updateModalityCommand.Type == 2) diff --git a/IRaCIS.Core.Application/Triggers/TrialCriterionSignTrigger.cs b/IRaCIS.Core.Application/Triggers/TrialCriterionSignTrigger.cs new file mode 100644 index 000000000..d0d21d603 --- /dev/null +++ b/IRaCIS.Core.Application/Triggers/TrialCriterionSignTrigger.cs @@ -0,0 +1,48 @@ +using AutoMapper; +using EasyCaching.Core; +using EntityFrameworkCore.Triggered; +using IRaCIS.Core.Application.Service; +using IRaCIS.Core.Application.ViewModel; +using IRaCIS.Core.Domain.Share; +using IRaCIS.Core.Infrastructure; + +namespace IRaCIS.Core.Application.Triggers +{ + /// + /// 因为可能先一致性核查通过,生成其他标准的任务了,新签名的标准也需要产生任务 + /// + public class TrialCriterionSignTrigger : IBeforeSaveTrigger + { + + private readonly IVisitTaskHelpeService _visitTaskHelpeService; + + + public TrialCriterionSignTrigger( + + IVisitTaskHelpeService visitTaskHelpeService) + { + + + _visitTaskHelpeService = visitTaskHelpeService; + } + + public async Task BeforeSave(ITriggerContext context, CancellationToken cancellationToken) + { + var trialCriterion = context.Entity; + + + if (context.ChangeType == ChangeType.Modified) + { + + // 一致性核查通过 生成读片任务 + if (context.UnmodifiedEntity?.ReadingInfoSignTime != trialCriterion.ReadingInfoSignTime && trialCriterion.ReadingInfoSignTime != null) + { + + + await _visitTaskHelpeService.BaseCritrionGenerateVisitTask(trialCriterion.TrialId, trialCriterion.Id); + } + + } + } + } +} \ No newline at end of file diff --git a/IRaCIS.Core.Domain/Image/DicomStudy.cs b/IRaCIS.Core.Domain/Image/DicomStudy.cs index 4693699b3..eb5b0ec4c 100644 --- a/IRaCIS.Core.Domain/Image/DicomStudy.cs +++ b/IRaCIS.Core.Domain/Image/DicomStudy.cs @@ -89,6 +89,8 @@ namespace IRaCIS.Core.Domain.Models public string BodyPartForEdit { get; set; } = string.Empty; + public string ModalityForEdit { get; set; } = string.Empty; + public bool CheckPassed { get; set; } diff --git a/IRaCIS.Core.Infra.EFCore/Repository/IRaCISContextExtension.cs b/IRaCIS.Core.Infra.EFCore/Repository/IRaCISContextExtension.cs index 3b472541e..1cf85e72b 100644 --- a/IRaCIS.Core.Infra.EFCore/Repository/IRaCISContextExtension.cs +++ b/IRaCIS.Core.Infra.EFCore/Repository/IRaCISContextExtension.cs @@ -102,10 +102,11 @@ namespace IRaCIS.Core.Infra.EFCore foreach (PropertyInfo prop in list) { + _dbContext.Entry(waitModifyEntity).Property(prop.Name).IsModified = true; + object value = prop.GetValue(applyObj); prop.SetValue(waitModifyEntity, value); - _dbContext.Entry(waitModifyEntity).Property(prop.Name).IsModified = true; }