diff --git a/IRaCIS.Core.API/_PipelineExtensions/Hangfire/HangfireConfig.cs b/IRaCIS.Core.API/_PipelineExtensions/Hangfire/HangfireConfig.cs index 5c5883030..48423534d 100644 --- a/IRaCIS.Core.API/_PipelineExtensions/Hangfire/HangfireConfig.cs +++ b/IRaCIS.Core.API/_PipelineExtensions/Hangfire/HangfireConfig.cs @@ -31,7 +31,7 @@ namespace IRaCIS.Core.API //周期性任务,1天执行一次 - RecurringJob.AddOrUpdate(t => t.MemoryCacheTrialStatus(), Cron.Daily); + RecurringJob.AddOrUpdate(t => t.ProjectStartCache(), Cron.Daily); #endregion diff --git a/IRaCIS.Core.Application/BackGroundJob/IRaCISCacheHangfireJob.cs b/IRaCIS.Core.Application/BackGroundJob/IRaCISCacheHangfireJob.cs index 577c26159..80a3d16ac 100644 --- a/IRaCIS.Core.Application/BackGroundJob/IRaCISCacheHangfireJob.cs +++ b/IRaCIS.Core.Application/BackGroundJob/IRaCISCacheHangfireJob.cs @@ -1,5 +1,6 @@ using EasyCaching.Core; using IRaCIS.Core.Domain.Share; +using Microsoft.EntityFrameworkCore.SqlServer.Query.Internal; using Microsoft.Extensions.Logging; namespace IRaCIS.Application.Services.BackGroundJob @@ -7,7 +8,13 @@ namespace IRaCIS.Application.Services.BackGroundJob public interface IIRaCISCacheHangfireJob { + + Task ProjectStartCache(); Task MemoryCacheTrialStatus(); + + Task MemoryCacheAnonymizeData(); + + Task CacheUserTypePermission(Guid? cacheUserTypeId); } public class IRaCISCacheHangfireJob: IIRaCISCacheHangfireJob { @@ -16,50 +23,77 @@ namespace IRaCIS.Application.Services.BackGroundJob private readonly ILogger _logger; private readonly IRepository _systemAnonymizationRepository; - public IRaCISCacheHangfireJob(IRepository trialRepository, IRepository systemAnonymizationRepository, IEasyCachingProvider provider,ILogger logger) + private readonly IRepository _userTypeMenuRepository; + + public IRaCISCacheHangfireJob(IRepository trialRepository, + IRepository systemAnonymizationRepository, IRepository userTypeMenuRepository, + IEasyCachingProvider provider,ILogger logger) { _trialRepository = trialRepository; _provider = provider; _logger = logger; _systemAnonymizationRepository = systemAnonymizationRepository; + _userTypeMenuRepository = userTypeMenuRepository; } - public async Task MemoryCacheTrialStatus() + + + public async Task ProjectStartCache() { - _logger.LogInformation("hangfire 定时任务开始~"); + _logger.LogInformation("hangfire 定时缓存项目状态任务开始~"); try { - await CacheTrialStatusAsync(); + await MemoryCacheTrialStatus(); - await CacheAnonymizeAsync(); + await MemoryCacheAnonymizeData(); + + await CacheUserTypePermission(); } catch (Exception e) { - _logger.LogError("hangfire 定时任务执行失败"+e.Message); + _logger.LogError("hangfire 定时任务执行失败" + e.Message); } - - _logger.LogInformation("hangfire 定时任务执行结束"); + _logger.LogInformation("hangfire 定时任务执行结束"); } - - - private async Task CacheTrialStatusAsync() + public async Task MemoryCacheTrialStatus() { - var list = await _trialRepository.Select(t => new { TrialId = t.Id, TrialStatusStr = t.TrialStatusStr }) + var list = await _trialRepository.Select(t => new { TrialId = t.Id, TrialStatusStr = t.TrialStatusStr }) .ToListAsync(); list.ForEach(t => _provider.Set(t.TrialId.ToString(), t.TrialStatusStr, TimeSpan.FromDays(7))); + } - private async Task CacheAnonymizeAsync() + + + + + + + public async Task MemoryCacheAnonymizeData() { - var systemAnonymizationList = await _systemAnonymizationRepository.Where(t => t.IsEnable).ToListAsync(); + var systemAnonymizationList = await _systemAnonymizationRepository.Where(t => t.IsEnable).ToListAsync(); _provider.Set(StaticData.Anonymize.Anonymize_AddFixedFiled, systemAnonymizationList.Where(t => t.IsAdd && t.IsFixed).ToList(), TimeSpan.FromDays(7)); _provider.Set(StaticData.Anonymize.Anonymize_AddIRCInfoFiled, systemAnonymizationList.Where(t => t.IsAdd && t.IsFixed == false).ToList(), TimeSpan.FromDays(7)); _provider.Set(StaticData.Anonymize.Anonymize_FixedField, systemAnonymizationList.Where(t => t.IsAdd == false && t.IsFixed).ToList(), TimeSpan.FromDays(7)); _provider.Set(StaticData.Anonymize.Anonymize_IRCInfoField, systemAnonymizationList.Where(t => t.IsAdd == false && t.IsFixed == false).ToList(), TimeSpan.FromDays(7)); } + + public async Task CacheUserTypePermission(Guid? cacheUserTypeId=null) + { + + var permissionList = await _userTypeMenuRepository.Where(t => t.Menu.MenuType == "F") + .WhereIf(cacheUserTypeId != null, t => t.UserTypeId == cacheUserTypeId.Value).Select(t => new { t.UserTypeId, t.Menu.PermissionStr }).ToListAsync(); + + foreach (var userTypeGroup in permissionList.GroupBy(t => t.UserTypeId)) + { + _provider.Set($"{StaticData.CacheKey.UserTypeId}_{userTypeGroup.Key}", userTypeGroup.Select(t => t.PermissionStr).ToList(), TimeSpan.FromDays(7)); + } + } + + } } \ No newline at end of file diff --git a/IRaCIS.Core.Application/IRaCIS.Core.Application.xml b/IRaCIS.Core.Application/IRaCIS.Core.Application.xml index 71e993e8f..b77121166 100644 --- a/IRaCIS.Core.Application/IRaCIS.Core.Application.xml +++ b/IRaCIS.Core.Application/IRaCIS.Core.Application.xml @@ -613,11 +613,13 @@ - + 手动生成入组确认 或者PD 进展的邮件 如果能发送,会返回文件的路径,否则会给出提示 - + + + diff --git a/IRaCIS.Core.Application/Service/Document/TrialEmailNoticeConfigService.cs b/IRaCIS.Core.Application/Service/Document/TrialEmailNoticeConfigService.cs index 3f46f1708..bfe39b7a3 100644 --- a/IRaCIS.Core.Application/Service/Document/TrialEmailNoticeConfigService.cs +++ b/IRaCIS.Core.Application/Service/Document/TrialEmailNoticeConfigService.cs @@ -19,6 +19,7 @@ using MiniSoftware; using IRaCIS.Core.Application.Service.Reading.Dto; using IRaCIS.Core.Domain.Share.Common; using System.IO; +using System.Linq; namespace IRaCIS.Core.Application.Service { @@ -38,15 +39,22 @@ namespace IRaCIS.Core.Application.Service public IRepository _visitTaskRepository { get; } public IRepository _trialUserRepository { get; } + public IRepository _subjectRepository { get; } + + public IRepository _subjectVisitRepository { get; } + public TrialEmailNoticeConfigService(IRepository trialEmailNoticeConfigRepository, IRepository visitTaskRepository, IRepository trialRepository, - IRepository trialUserRepository, IRepository taskMedicalReviewRepository) + IRepository trialUserRepository, IRepository taskMedicalReviewRepository, IRepository subjectRepository, IRepository subjectVisitRepository) { _trialEmailNoticeConfigRepository = trialEmailNoticeConfigRepository; _visitTaskRepository = visitTaskRepository; this._trialRepository = trialRepository; _trialUserRepository = trialUserRepository; _taskMedicalReviewRepository = taskMedicalReviewRepository; + _subjectRepository = subjectRepository; + + _subjectVisitRepository = subjectVisitRepository; } /// @@ -821,19 +829,239 @@ namespace IRaCIS.Core.Application.Service /// /// 手动生成入组确认 或者PD 进展的邮件 如果能发送,会返回文件的路径,否则会给出提示 /// - /// + /// + /// + /// /// [HttpPut] - public async Task ManualGenerateEmailFile(Guid visitTaskId) + public async Task ManualGenerateEmailFile(Guid subjectId, Guid trialReadingCriterionId, CommonDocumentBusinessScenario businessScenarioEnum) { - var filePath = await BaseBusinessScenarioSendEmailAsync(visitTaskId, true, EmailStoreSendMode.OnlyStoreLocalNotSentEmail, string.Empty); - if (string.IsNullOrEmpty(filePath)) + var trialConfig = await _subjectRepository.Where(t => t.Id == subjectId).Select(t => new { t.Trial.IsEnrollementQualificationConfirm, t.Trial.IsPDProgressView }).FirstNotNullAsync(); + + //找到入组确认 或者Pd 进展 已生成任务的 访视 + var subjectVisitList = await _subjectVisitRepository.Where(t => t.SubjectId == subjectId & t.CheckState == CheckStateEnum.CVPassed && (t.IsEnrollmentConfirm == true || t.PDState == PDStateEnum.PDProgress)).ToListAsync(); + + if (businessScenarioEnum == CommonDocumentBusinessScenario.EnrollConfirmed) { - return ResponseOutput.NotOk("该任务不符合发送邮件的条件"); + + if (trialConfig.IsEnrollementQualificationConfirm == false) + { + return ResponseOutput.NotOk("项目未配置入组确认!"); + + } + var exisitBaseline = subjectVisitList.FirstOrDefault(t => t.IsEnrollmentConfirm); + if (exisitBaseline == null) + { + return ResponseOutput.NotOk("不存在配置了入组确认的并且生成任务的基线访视"); + } + else + { + //入组确认不用管项目的 有序 无序 单重 双重 阅片 + + var task = await _visitTaskRepository.Where(t => t.SourceSubjectVisitId == exisitBaseline.Id && t.TaskState == TaskState.Effect && t.IsAnalysisCreate == false + && t.ReadingTaskState == ReadingTaskState.HaveSigned && t.TrialReadingCriterionId == trialReadingCriterionId).FirstOrDefaultAsync(); + + //如果存在做完的该任务 + + if (task == null) + { + return ResponseOutput.NotOk("基线任务没有阅片完!"); + } + else + { + var filePath = await BaseBusinessScenarioSendEmailAsync(task.Id, true, EmailStoreSendMode.OnlyStoreLocalNotSentEmail, string.Empty); + + return ResponseOutput.Ok(new { RelaTivePath = filePath, TaskName = task.TaskName, VisitTaskId = task.Id }); + + + } + + } } - return ResponseOutput.Ok(filePath); + else if (businessScenarioEnum == CommonDocumentBusinessScenario.PDConfirmed) + { + + if (trialConfig.IsPDProgressView == false) + { + return ResponseOutput.NotOk("项目未配置PD进展!"); + } + + //是否是截止访视 截止访视在全局发 否则就在当前访视发 + + var pdSubjectVisitIdList = subjectVisitList.Where(t => t.PDState == PDStateEnum.PDProgress).OrderBy(t => t.VisitNum).Select(t => (Guid?)t.Id).ToList(); + + if (pdSubjectVisitIdList.Count == 0) + { + return ResponseOutput.NotOk("不存在配置了Pd进展的并且生成任务的基线访视"); + } + + + var currentLatestPdVisitId = pdSubjectVisitIdList.Last(); + //标准配置 + var trialReadingCriterionConfig = await _repository.Where(t => t.Id == trialReadingCriterionId).Select(t => new + { TrialReadingCriterionId = t.Id, t.ReadingType, t.IsReadingTaskViewInOrder, t.CriterionType, t.ArbitrationRule }).FirstNotNullAsync(); + + // 项目双重 + if (trialReadingCriterionConfig.ReadingType == ReadingMethod.Double) + { + //仲裁在访视上面 + if (trialReadingCriterionConfig.ArbitrationRule == ArbitrationRule.Visit) + { + //在两位阅片人读完访视后,如果有裁判者等裁判读完,如果无裁判则等第二个人的读完 + + var taskList = await _visitTaskRepository.Where(t => t.SourceSubjectVisitId == currentLatestPdVisitId && t.TrialReadingCriterionId == trialReadingCriterionId && t.IsAnalysisCreate == false + && t.TaskState == TaskState.Effect && (t.ReadingCategory == ReadingCategory.Visit || t.ReadingCategory == ReadingCategory.Judge)).ToListAsync(); + + var totalTaskCount = taskList.Count; + var finishedCount = taskList.Where(t => t.ReadingTaskState == ReadingTaskState.HaveSigned).Count(); + + + //发送随访的 + if (totalTaskCount == 2 && totalTaskCount == finishedCount) + { + var task = taskList.FirstOrDefault(t => t.ReadingCategory == ReadingCategory.Visit); + + var filePath = await BaseBusinessScenarioSendEmailAsync(task.Id, true, EmailStoreSendMode.OnlyStoreLocalNotSentEmail, string.Empty); + + return ResponseOutput.Ok(new { RelaTivePath = filePath, TaskName = task.TaskName, VisitTaskId = task.Id }); + } + //发送全局 + else if (totalTaskCount == 3 && totalTaskCount == finishedCount) + { + var task = taskList.FirstOrDefault(t => t.ReadingCategory == ReadingCategory.Judge); + + var filePath = await BaseBusinessScenarioSendEmailAsync(task.Id, true, EmailStoreSendMode.OnlyStoreLocalNotSentEmail, string.Empty); + + return ResponseOutput.Ok(new { RelaTivePath = filePath, TaskName = task.TaskName, VisitTaskId = task.Id }); + } + else + { + return ResponseOutput.NotOk("当前Subject最新PD访视阅片任务完成状态不符合发送条件"); + } + + + + + } + //仲裁在阅片期上 + else if (trialReadingCriterionConfig.ArbitrationRule == ArbitrationRule.Reading) + { + var existReadModule = await _repository.Where(t => t.TrialReadingCriterionId == trialReadingCriterionId && t.SubjectVisitId == currentLatestPdVisitId && t.ReadingSetType == ReadingSetType.ImageReading) + .FirstOrDefaultAsync(); + + if (existReadModule == null) + { + return ResponseOutput.NotOk("项目配置了阅片期仲裁,但是当前Subject最新PD访视没有影像学阅片期"); + } + else + { + var taskList = await _visitTaskRepository.Where(t => t.TrialReadingCriterionId == trialReadingCriterionId && t.IsAnalysisCreate == false && t.TaskState == TaskState.Effect && t.SouceReadModuleId == existReadModule.Id + && (t.ReadingCategory == ReadingCategory.Global || t.ReadingCategory == ReadingCategory.Judge)).ToListAsync(); + + var totalTaskCount = taskList.Count; + var finishedCount = taskList.Where(t => t.ReadingTaskState == ReadingTaskState.HaveSigned).Count(); + + + + //发送全局的 + if (totalTaskCount == 2 && totalTaskCount == finishedCount) + { + var task = taskList.FirstOrDefault(t => t.ReadingCategory == ReadingCategory.Global); + + var filePath = await BaseBusinessScenarioSendEmailAsync(task.Id, true, EmailStoreSendMode.OnlyStoreLocalNotSentEmail, string.Empty); + + return ResponseOutput.Ok(new { RelaTivePath = filePath, TaskName = task.TaskName, VisitTaskId = task.Id }); + } + //发送全局裁判的 + else if (totalTaskCount == 3 && totalTaskCount == finishedCount) + { + var task = taskList.FirstOrDefault(t => t.ReadingCategory == ReadingCategory.Judge); + + var filePath = await BaseBusinessScenarioSendEmailAsync(task.Id, true, EmailStoreSendMode.OnlyStoreLocalNotSentEmail, string.Empty); + + return ResponseOutput.Ok(new { RelaTivePath = filePath, TaskName = task.TaskName, VisitTaskId = task.Id }); + } + + + else + { + return ResponseOutput.NotOk("当前Subject最新PD访视阅片期任务完成状态不符合发送条件"); + } + } + + + } + else + { + return ResponseOutput.NotOk("未定义该仲裁规则发送业务逻辑!"); + } + } + // 项目单重 判断最新的Pd 访视是否完成 是否有阅片期即可 + else if (trialReadingCriterionConfig.ReadingType == ReadingMethod.Single) + { + + + + var task = await _visitTaskRepository.Where(t => t.SourceSubjectVisitId == currentLatestPdVisitId && t.TaskState == TaskState.Effect && t.IsAnalysisCreate == false + && t.ReadingTaskState == ReadingTaskState.HaveSigned && t.TrialReadingCriterionId == trialReadingCriterionId).FirstOrDefaultAsync(); + + + if (task == null) + { + return ResponseOutput.NotOk("当前Subject最新PD访视任务未阅片完成"); + } + else + { + //存在阅片期 那么就是截止访视 + + var existReadModule = await _repository.Where(t => t.TrialReadingCriterionId == trialReadingCriterionId && t.SubjectVisitId == currentLatestPdVisitId && t.ReadingSetType == ReadingSetType.ImageReading) + .FirstOrDefaultAsync(); + if (existReadModule != null) + { + + var global = await _visitTaskRepository.Where(t => t.SouceReadModuleId == currentLatestPdVisitId && t.TaskState == TaskState.Effect && t.IsAnalysisCreate == false + && t.ReadingTaskState == ReadingTaskState.HaveSigned && t.TrialReadingCriterionId == trialReadingCriterionId).FirstOrDefaultAsync(); + + + if (global != null) + { + var filePath = await BaseBusinessScenarioSendEmailAsync(global.Id, true, EmailStoreSendMode.OnlyStoreLocalNotSentEmail, string.Empty); + + return ResponseOutput.Ok(new { RelaTivePath = filePath, TaskName = task.TaskName, VisitTaskId = task.Id }); + } + else + { + return ResponseOutput.NotOk("当前Subject阅片期任务未阅片完成"); + } + + } + else//非截止访视 在访视读完后,发送 + { + var filePath = await BaseBusinessScenarioSendEmailAsync(task.Id, true, EmailStoreSendMode.OnlyStoreLocalNotSentEmail, string.Empty); + + return ResponseOutput.Ok(new { RelaTivePath = filePath, TaskName = task.TaskName, VisitTaskId = task.Id }); + } + } + + + } + else + { + return ResponseOutput.NotOk("当前项目配置,未定义单双重外发送业务逻辑!"); + } + + } + + else + { + return ResponseOutput.NotOk("当前项目配置,未定义发送业务逻辑!"); + } + + + + } /// diff --git a/IRaCIS.Core.Domain/Management/UserTypeMenu.cs b/IRaCIS.Core.Domain/Management/UserTypeMenu.cs index b32311eea..017cf37a1 100644 --- a/IRaCIS.Core.Domain/Management/UserTypeMenu.cs +++ b/IRaCIS.Core.Domain/Management/UserTypeMenu.cs @@ -15,6 +15,7 @@ namespace IRaCIS.Core.Domain.Models [JsonIgnore] [ForeignKey("UserTypeId")] public UserType UserType { get; set; } + } } diff --git a/IRaCIS.Core.Domain/_Config/_StaticData.cs b/IRaCIS.Core.Domain/_Config/_StaticData.cs index ac9372d2d..41f9c6dee 100644 --- a/IRaCIS.Core.Domain/_Config/_StaticData.cs +++ b/IRaCIS.Core.Domain/_Config/_StaticData.cs @@ -72,6 +72,9 @@ public static class StaticData public static string StudyMaxCode = "StudyMaxCode"; public static string TaskMaxCode = "TaskMaxCode"; + + public const string UserTypeId = "UserTypeId"; + }