diff --git a/IRaCIS.Core.Application/IRaCIS.Core.Application.xml b/IRaCIS.Core.Application/IRaCIS.Core.Application.xml index 512b1297b..71bf4b20b 100644 --- a/IRaCIS.Core.Application/IRaCIS.Core.Application.xml +++ b/IRaCIS.Core.Application/IRaCIS.Core.Application.xml @@ -2154,7 +2154,7 @@ - + 账号验证,获取账号角色信息 获取临时token @@ -12648,7 +12648,7 @@ - + IR影像阅片 @@ -12993,6 +12993,14 @@ + + + 前端 仅仅释放的时候使用,领取是后端调用该方法 + + + + + 重置阅片时间 登录和解锁调用 diff --git a/IRaCIS.Core.Application/MassTransit/Consumer/SubjectCriterionClaimCancelConsumer.cs b/IRaCIS.Core.Application/MassTransit/Consumer/SubjectCriterionClaimCancelConsumer.cs new file mode 100644 index 000000000..c284c21dc --- /dev/null +++ b/IRaCIS.Core.Application/MassTransit/Consumer/SubjectCriterionClaimCancelConsumer.cs @@ -0,0 +1,38 @@ +using IRaCIS.Core.Domain; +using IRaCIS.Core.Domain._DomainEvent; +using IRaCIS.Core.Domain.Models; +using MassTransit; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace IRaCIS.Core.Application.MassTransit.Consumer +{ + public class SubjectCriterionClaimCancelConsumer(IRepository _visitTaskRepository) : IConsumer + { + public async Task Consume(ConsumeContext context) + { + + Log.Logger.Warning($"定时任务取消领取!{context.Message.ToJsonStr()}"); + bool isInOrder = context.Message.IsInOrder; + + if (isInOrder) + { + Guid subjectId = (Guid)context.Message.SubjectId; + + Guid trialReadingCriterionId = (Guid)context.Message.TrialReadingCriterionId; + + await _visitTaskRepository.BatchUpdateNoTrackingAsync(t => t.SubjectId == subjectId && t.TrialReadingCriterionId == trialReadingCriterionId && t.ReadingTaskState != ReadingTaskState.HaveSigned, u => new VisitTask() { SubjectCriterionClaimUserId = null }); + + } + else + { + Guid id = (Guid)context.Message.VisitTaskId; + + await _visitTaskRepository.UpdatePartialFromQueryAsync(t => t.Id == id && t.ReadingTaskState != ReadingTaskState.HaveSigned, u => new VisitTask() { DoctorUserId = null }, true); + } + } + } +} diff --git a/IRaCIS.Core.Application/Service/Reading/Dto/ReadingImageTaskViewModel.cs b/IRaCIS.Core.Application/Service/Reading/Dto/ReadingImageTaskViewModel.cs index 586df651b..93efa7aff 100644 --- a/IRaCIS.Core.Application/Service/Reading/Dto/ReadingImageTaskViewModel.cs +++ b/IRaCIS.Core.Application/Service/Reading/Dto/ReadingImageTaskViewModel.cs @@ -3074,4 +3074,17 @@ namespace IRaCIS.Core.Application.Service.Reading.Dto //{ //} + + public class ClaimSubjectDto + { + public bool IsInOrder { get; set; } + + public Guid? VisitTaskId { get; set; } + + public Guid TrialReadingCriterionId { get; set; } + + public Guid SubejctId { get; set; } + + public bool IsClaim { get; set; } + } } diff --git a/IRaCIS.Core.Application/Service/Reading/ReadingImageTask/ReadingImageTaskService.cs b/IRaCIS.Core.Application/Service/Reading/ReadingImageTask/ReadingImageTaskService.cs index 0f4927f11..140e8df80 100644 --- a/IRaCIS.Core.Application/Service/Reading/ReadingImageTask/ReadingImageTaskService.cs +++ b/IRaCIS.Core.Application/Service/Reading/ReadingImageTask/ReadingImageTaskService.cs @@ -12,13 +12,18 @@ using IRaCIS.Core.Infra.EFCore.Common; using IRaCIS.Core.Infrastructure; using MassTransit; using Microsoft.AspNetCore.Mvc; +using Microsoft.EntityFrameworkCore.Metadata.Builders; +using Microsoft.EntityFrameworkCore.Metadata; using Microsoft.Extensions.Options; using Newtonsoft.Json; using Newtonsoft.Json.Linq; using NPOI.POIFS.Properties; using NPOI.SS.Formula.Functions; using Panda.DynamicWebApi.Attributes; +using System.Reactive.Concurrency; using ZiggyCreatures.Caching.Fusion; +using IRaCIS.Core.Domain.BaseModel; +using IRaCIS.Core.Domain._DomainEvent; namespace IRaCIS.Core.Application.Service { @@ -30,6 +35,7 @@ namespace IRaCIS.Core.Application.Service IRepository _noneDicomStudyRepository, IRepository _visitTaskRepository, IRepository _trialRepository, + IMessageScheduler _scheduler, IRepository _readingTableQuestionAnswerRepository, IRepository _readingOncologyTaskInfoRepository, IVisitTaskHelpeService _visitTaskHelpeService, @@ -72,9 +78,9 @@ namespace IRaCIS.Core.Application.Service [HttpPost] public async Task GetTNMValue(TNMValueDto inDto) { - var result= await _visitTaskRepository.Where(x=>x.Id==inDto.VisitTaskId).Select(x => new TNMValueDto() + var result = await _visitTaskRepository.Where(x => x.Id == inDto.VisitTaskId).Select(x => new TNMValueDto() { - VisitTaskId=inDto.VisitTaskId, + VisitTaskId = inDto.VisitTaskId, TNMValue = x.TNMValue }).FirstOrDefaultAsync(); return result; @@ -93,7 +99,7 @@ namespace IRaCIS.Core.Application.Service await _visitTaskRepository.UpdatePartialFromQueryAsync(x => x.Id == inDto.VisitTaskId, x => new VisitTask() { TNMValue = inDto.TNMValue - },true); + }, true); return inDto; } @@ -771,6 +777,11 @@ namespace IRaCIS.Core.Application.Service } + if (await _visitTaskRepository.AnyAsync(x => x.Id == visitTaskid && x.DoctorUserId != _userInfo.UserRoleId && x.SubjectCriterionClaimUserId != _userInfo.UserRoleId)) + { + throw new BusinessValidationFailedException(_localizer["其他人已领取该任务,不允许操作"]); + } + if (await _visitTaskRepository.AnyAsync(x => x.Id == visitTaskid && x.TaskState != TaskState.Effect)) { throw new BusinessValidationFailedException(_localizer["ReadingImage_Beinvalid"]); @@ -2858,7 +2869,11 @@ namespace IRaCIS.Core.Application.Service TrialReadingCriterionId = x.TrialReadingCriterionId, }).FirstOrDefault(); - + if (task != null) + { + // 有序 自动领取该Subject + await ClaimOrCancelSubjectAsync(new ClaimSubjectDto() { IsClaim = true, SubejctId = task.SubjectId, TrialReadingCriterionId = task.TrialReadingCriterionId, VisitTaskId = task.VisitTaskId, IsInOrder = true }); + } } else if (inDto.SubjectId != null && trialReadingCriterion.IsReadingTaskViewInOrder == ReadingOrder.SubjectRandom) @@ -2985,6 +3000,12 @@ namespace IRaCIS.Core.Application.Service TrialReadingCriterionId = x.TrialReadingCriterionId, }).Skip(skipcount).FirstOrDefaultAsync(); + if (task != null) + { + // 无序 + await ClaimOrCancelSubjectAsync(new ClaimSubjectDto() { IsClaim = true, VisitTaskId = task.VisitTaskId, IsInOrder = false }); + } + } if (task == null) @@ -3172,6 +3193,77 @@ namespace IRaCIS.Core.Application.Service return true; } + + + /// + /// 前端 仅仅释放的时候使用,领取是后端调用该方法 + /// + /// + /// + /// + [HttpPost] + public async Task ClaimOrCancelSubjectAsync(ClaimSubjectDto claimSubjectDto) + { + + + //有序 用SubjectCriterionClaimUserId 某个标准的所有任务,该字段保持一致 + if (claimSubjectDto.IsInOrder) + { + + if (claimSubjectDto.IsClaim) + { + //每个subject 每个标准的领取放在 任务上 免得加表 + if (_visitTaskRepository.Any(t => t.Id == claimSubjectDto.SubejctId && t.TrialReadingCriterionId == claimSubjectDto.TrialReadingCriterionId + && t.SubjectCriterionClaimUserId != _userInfo.UserRoleId && t.SubjectCriterionClaimUserId != null)) + { + throw new BusinessValidationFailedException(_localizer["ReadingImageTask_TaskTaken"]); + } + else + { + await _visitTaskRepository.BatchUpdateNoTrackingAsync(t => t.SubjectId == claimSubjectDto.SubejctId && t.TrialReadingCriterionId == claimSubjectDto.TrialReadingCriterionId, u => new VisitTask() { SubjectCriterionClaimUserId = _userInfo.UserRoleId }); + + //列表可以看到当前阅片人是谁 + await _visitTaskRepository.BatchUpdateNoTrackingAsync(t => t.Id == claimSubjectDto.VisitTaskId, u => new VisitTask() { DoctorUserId = _userInfo.UserRoleId }); + } + + + var domainEvent = new SubjectCriterionClaimCancelEvent() { SubjectId = claimSubjectDto.SubejctId, TrialReadingCriterionId = claimSubjectDto.TrialReadingCriterionId, IsInOrder = claimSubjectDto.IsInOrder }; + await _scheduler.SchedulePublish(DateTime.Now.AddDays(1), (object)domainEvent); + + + //BackgroundJob.Schedule(t => t.CancelQCObtaion(subjectVisitId, DateTime.Now), TimeSpan.FromHours(1)); + + } + else + { + await _visitTaskRepository.BatchUpdateNoTrackingAsync(t => t.SubjectId == claimSubjectDto.SubejctId && t.TrialReadingCriterionId == claimSubjectDto.TrialReadingCriterionId && t.ReadingTaskState != ReadingTaskState.HaveSigned, u => new VisitTask() { SubjectCriterionClaimUserId = null }); + } + } + //无序 直接用DoctorUserId 当做领取人 + else + { + if (claimSubjectDto.IsClaim) + { + if (_visitTaskRepository.Any(t => t.Id == claimSubjectDto.VisitTaskId && t.DoctorUserId != _userInfo.UserRoleId && t.DoctorUserId != null)) + { + throw new BusinessValidationFailedException(_localizer["ReadingImageTask_TaskTaken"]); + } + else + { + await _visitTaskRepository.UpdatePartialFromQueryAsync(t => t.Id == claimSubjectDto.VisitTaskId, u => new VisitTask() { DoctorUserId = _userInfo.UserRoleId }, true); + + } + + var domainEvent = new SubjectCriterionClaimCancelEvent() { VisitTaskId = claimSubjectDto.VisitTaskId, IsInOrder = claimSubjectDto.IsInOrder }; + await _scheduler.SchedulePublish(DateTime.Now.AddDays(1), (object)domainEvent); + + + } + } + + + } + /// /// 重置阅片时间 登录和解锁调用 /// diff --git a/IRaCIS.Core.Domain/_DomainEvent/SubjectCriterionClaimCancelEvent.cs b/IRaCIS.Core.Domain/_DomainEvent/SubjectCriterionClaimCancelEvent.cs new file mode 100644 index 000000000..3be6e7970 --- /dev/null +++ b/IRaCIS.Core.Domain/_DomainEvent/SubjectCriterionClaimCancelEvent.cs @@ -0,0 +1,23 @@ +using IRaCIS.Core.Domain.BaseModel; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace IRaCIS.Core.Domain._DomainEvent +{ + public class SubjectCriterionClaimCancelEvent : DomainEvent + { + public Guid? SubjectId { get; set; } + + public Guid? TrialReadingCriterionId { get; set; } + + + public Guid? VisitTaskId { get; set; } + + + public bool IsInOrder { get; set; } + + } +}