diff --git a/IRaCIS.Core.Application/BackGroundJob/IRaCISCHangfireJob.cs b/IRaCIS.Core.Application/BackGroundJob/IRaCISCHangfireJob.cs index 514df5174..7e062a0f8 100644 --- a/IRaCIS.Core.Application/BackGroundJob/IRaCISCHangfireJob.cs +++ b/IRaCIS.Core.Application/BackGroundJob/IRaCISCHangfireJob.cs @@ -9,6 +9,7 @@ using Microsoft.Extensions.Configuration; using Microsoft.Extensions.Logging; using Newtonsoft.Json; using SharpCompress.Common; +using ZiggyCreatures.Caching.Fusion; namespace IRaCIS.Application.Services.BackGroundJob { @@ -21,77 +22,45 @@ namespace IRaCIS.Application.Services.BackGroundJob Task InitHangfireJobTaskAsync(); } - public class IRaCISCHangfireJob : IIRaCISHangfireJob + public class IRaCISCHangfireJob(IRepository _trialRepository, + IEasyCachingProvider _provider, + ILogger _logger, + IRepository _systemAnonymizationRepository, + IRepository _internationalizationRepository, + IRepository _trialEmailNoticeConfigRepository + ) : IIRaCISHangfireJob { public static string JsonFileFolder = Path.Combine(AppContext.BaseDirectory, StaticData.Folder.Resources); - private readonly IRepository _trialRepository; - private readonly IEasyCachingProvider _provider; - private readonly ILogger _logger; - private readonly IRepository _systemAnonymizationRepository; - private readonly IRepository _trialEmailNoticeConfigRepository; - private readonly IRepository _internationalizationRepository; - - - - public IRaCISCHangfireJob(IRepository trialRepository, ILogger logger, IEasyCachingProvider provider, IRepository trialEmailNoticeConfigRepository, IRepository internationalizationRepository, IRepository systemAnonymizationRepository) - { - _trialRepository = trialRepository; - _provider = provider; - _logger = logger; - _trialEmailNoticeConfigRepository = trialEmailNoticeConfigRepository; - _internationalizationRepository = internationalizationRepository; - _systemAnonymizationRepository = systemAnonymizationRepository; - } public async Task InitHangfireJobTaskAsync() { _logger.LogInformation("项目启动 hangfire 任务初始化 执行开始~"); - - //项目状态 立即加载到缓存中 - await MemoryCacheTrialStatusAsync(); - - await MemoryCacheAnonymizeData(); - - - //创建项目缓存 定时任务 - HangfireJobHelper.AddOrUpdateInitCronJob("RecurringJob_Cache_TrialState", t => t.MemoryCacheTrialStatusAsync(), Cron.Daily()); - - //初始化 + //初始化国际化 await InternationalizationHelper.InitInternationlizationDataAndWatchJsonFileAsync(_internationalizationRepository); //创建邮件定时任务 await InitSysAndTrialCronJobAsync(); + #region 废弃 + ////项目状态 立即加载到缓存中 + //await MemoryCacheTrialStatusAsync(); + + ////await MemoryCacheAnonymizeData(); + + + ////创建项目缓存 定时任务 + //HangfireJobHelper.AddOrUpdateInitCronJob("RecurringJob_Cache_TrialState", t => t.MemoryCacheTrialStatusAsync(), Cron.Daily()); + #endregion + _logger.LogInformation("项目启动 hangfire 任务初始化 执行结束"); } - /// - /// 缓存项目状态 - /// - /// - public async Task MemoryCacheTrialStatusAsync() - { - 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))); - - } - - public async Task MemoryCacheAnonymizeData() - { - 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)); - } @@ -136,6 +105,36 @@ namespace IRaCIS.Application.Services.BackGroundJob } + + + #region 废弃 前端上传的时候获取 + + + /// + /// 缓存项目状态--之前是启动的时候就获取所有的项目进行缓存,加上定时任务刷新,现在的话,改为是按照需要进行缓存请求数据库 + /// + /// + public async Task MemoryCacheTrialStatusAsync() + { + + 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))); + + } + public async Task MemoryCacheAnonymizeData() + { + 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)); + } + + + #endregion } diff --git a/IRaCIS.Core.Application/BaseService.cs b/IRaCIS.Core.Application/BaseService.cs index 00df0c376..1d87bdb1f 100644 --- a/IRaCIS.Core.Application/BaseService.cs +++ b/IRaCIS.Core.Application/BaseService.cs @@ -9,6 +9,7 @@ using Panda.DynamicWebApi.Attributes; using System.Diagnostics.CodeAnalysis; using IRaCIS.Core.Domain.Share; using Microsoft.AspNetCore.Mvc; +using ZiggyCreatures.Caching.Fusion; namespace IRaCIS.Core.Application { @@ -32,7 +33,7 @@ namespace IRaCIS.Core.Application public IWebHostEnvironment _hostEnvironment { get; set; } - + public IFusionCache _fusionCache { get; set; } public static IResponseOutput Null404NotFound(TEntity? businessObject) where TEntity : class @@ -60,6 +61,9 @@ namespace IRaCIS.Core.Application [MemberNotNull(nameof(_hostEnvironment))] public IWebHostEnvironment _hostEnvironment { get; set; } + [MemberNotNull(nameof(_fusionCache))] + public IFusionCache _fusionCache { get; set; } + } #endregion @@ -81,8 +85,9 @@ namespace IRaCIS.Core.Application [MemberNotNull(nameof(_localizer))] public IStringLocalizer _localizer { get; set; } + [MemberNotNull(nameof(_fusionCache))] + public IFusionCache _fusionCache { get; set; } - } [TypeFilter(typeof(UnifiedApiResultFilter))] @@ -97,6 +102,8 @@ namespace IRaCIS.Core.Application public IStringLocalizer _localizer { get; set; } + public IFusionCache _fusionCache { get; set; } + public static IResponseOutput Null404NotFound(TEntity? businessObject) where TEntity : class { return new ResponseOutput() diff --git a/IRaCIS.Core.Application/BusinessFilter/TrialResourceFilter.cs b/IRaCIS.Core.Application/BusinessFilter/TrialResourceFilter.cs index f7dfe2583..683059714 100644 --- a/IRaCIS.Core.Application/BusinessFilter/TrialResourceFilter.cs +++ b/IRaCIS.Core.Application/BusinessFilter/TrialResourceFilter.cs @@ -1,10 +1,12 @@ using EasyCaching.Core; +using IRaCIS.Core.Application.Helper; using IRaCIS.Core.Domain.Share; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc.Filters; using Microsoft.Extensions.Localization; using System.Text.RegularExpressions; +using ZiggyCreatures.Caching.Fusion; using static IRaCIS.Core.Domain.Share.StaticData; namespace IRaCIS.Core.Application.Filter @@ -16,47 +18,36 @@ namespace IRaCIS.Core.Application.Filter { private readonly IEasyCachingProvider _provider; private readonly IUserInfo _userInfo; - + private readonly IFusionCache _fusionCache; public IStringLocalizer _localizer; - private readonly List _trialOptList=new List(); + private readonly IRepository _trialRepository; + private readonly List _trialOptList = new List(); - public TrialResourceFilter(IEasyCachingProvider provider, IStringLocalizer localizer , IUserInfo userInfo, string trialOpt = null, string trialOpt2 = null, string trialOpt3 = null) + public TrialResourceFilter(IFusionCache fusionCache, IRepository trialRepository, IEasyCachingProvider provider, IStringLocalizer localizer, IUserInfo userInfo, string trialOpt = null, string trialOpt2 = null, string trialOpt3 = null) { + _fusionCache = fusionCache; _provider = provider; _userInfo = userInfo; _localizer = localizer; - //_trialOpt = trialOpt; + _trialRepository = trialRepository; - if (!string.IsNullOrWhiteSpace(trialOpt)) _trialOptList.Add(trialOpt.Trim()); + if (!string.IsNullOrWhiteSpace(trialOpt)) _trialOptList.Add(trialOpt.Trim()); if (!string.IsNullOrWhiteSpace(trialOpt2)) _trialOptList.Add(trialOpt2.Trim()); if (!string.IsNullOrWhiteSpace(trialOpt3)) _trialOptList.Add(trialOpt3.Trim()); - } - - - //public TrialResourceFilter(IEasyCachingProvider provider, IUserInfo userInfo) - //{ - // _provider = provider; - // _userInfo = userInfo; - //} - - - - - //优先选择异步的方法 public async Task OnResourceExecutionAsync(ResourceExecutingContext context, ResourceExecutionDelegate next) { - // var typeFilter = context.ActionDescriptor.EndpointMetadata.Where(t => t.GetType() == typeof(TypeFilterAttribute)).Select(t => (TypeFilterAttribute)t).ToList().FirstOrDefault(); - //var _trialOptList= typeFilter.Arguments.Select(t => t.ToString()).ToList(); + // var typeFilter = context.ActionDescriptor.EndpointMetadata.Where(t => t.GetType() == typeof(TypeFilterAttribute)).Select(t => (TypeFilterAttribute)t).ToList().FirstOrDefault(); + //var _trialOptList= typeFilter.Arguments.Select(t => t.ToString()).ToList(); #region 处理新的用户类型,不能操作项目相关接口 // 后期列举出具体的类型,其他任何用户类型,都不允许操作 - if (_userInfo.UserTypeEnumInt == (int)UserTypeEnum.CRA && _userInfo.RequestUrl.ToLower()!= "TrialDocument/userConfirm".ToLower()) + if (_userInfo.UserTypeEnumInt == (int)UserTypeEnum.CRA && _userInfo.RequestUrl.ToLower() != "TrialDocument/userConfirm".ToLower()) { //---对不起,您的账户没有操作权限。 context.Result = new JsonResult(ResponseOutput.NotOk(_localizer["TrialResource_NoAccessPermission"])); @@ -97,7 +88,7 @@ namespace IRaCIS.Core.Application.Filter } else { - //---正则取请求Refer 中trialId 失败,请联系开发人员核查 + //---正则取请求Refer 中trialId 失败,请联系开发人员核查 context.Result = new JsonResult(ResponseOutput.NotOk(_localizer["TrialResource_ReferTrialIdFailed"])); } @@ -128,20 +119,20 @@ namespace IRaCIS.Core.Application.Filter if (matchResult.Success) { //有可能匹配错误 "trialId":"","documentId":"b8180000-3e2c-0016-9fe0-08da33f96236" 从缓存里面验证下 - var cacheResultDic = _provider.GetAll(new[] { matchResult.Value }); - var trialStatusStr = cacheResultDic[matchResult.Value.ToLower()].Value; + trialIdStr = matchResult.Value; - if (!string.IsNullOrWhiteSpace(trialStatusStr)) + var trialStatusStr = await _fusionCache.GetOrSetAsync(CacheKeys.Trial(trialIdStr), _ => CacheHelper.GetTrialStatusAsync(Guid.Parse(trialIdStr), _trialRepository), TimeSpan.FromDays(7)); + + if (string.IsNullOrWhiteSpace(trialStatusStr)) { - trialIdStr = matchResult.Value; + //数据库 检查该项目Id不对 + context.Result = new JsonResult(ResponseOutput.NotOk(_localizer["TrialResource_ReferTrialIdFailed"])); } - - } else { - //---正则取请求Refer 中trialId 失败,请联系开发人员核查 + //---正则取请求Refer 中trialId 失败,请联系开发人员核查 context.Result = new JsonResult(ResponseOutput.NotOk(_localizer["TrialResource_ReferTrialIdFailed"])); } @@ -153,34 +144,12 @@ namespace IRaCIS.Core.Application.Filter } //通过path 或者body 找到trialId 了 - if ( !string.IsNullOrWhiteSpace(trialIdStr)) + if (!string.IsNullOrWhiteSpace(trialIdStr)) { - - //如果没缓存数据,可能定时任务没执行或者缓存丢失 在此重新缓存 - if (_provider.GetCount() == 0) - { - - var _trialRepository = context.HttpContext.RequestServices.GetService(typeof(IRepository)) as IRepository; - - var list = _trialRepository.IfNullThrowException().Select(t => new { TrialId = t.Id, TrialStatusStr = t.TrialStatusStr }) - .ToList(); - - list.ForEach(t => _provider.Set(t.TrialId.ToString(), t.TrialStatusStr, TimeSpan.FromDays(7))); - } - - var cacheResultDic = _provider.GetAll(new[] { trialIdStr }); - - var trialStatusStr = cacheResultDic[trialIdStr].Value; - - //意外 导致缓存过期,调整服务器时间,测试不想重启程序 - if (string.IsNullOrWhiteSpace(trialStatusStr)) - { - var trialRepository = context.HttpContext.RequestServices.GetService(typeof(IRepository)) as IRepository; - trialStatusStr = trialRepository?.Where(t => t.Id == Guid.Parse(trialIdStr)).Select(t => t.TrialStatusStr).FirstOrDefault(); - } + var trialStatusStr = await _fusionCache.GetOrSetAsync(CacheKeys.Trial(trialIdStr), _ => CacheHelper.GetTrialStatusAsync(Guid.Parse(trialIdStr), _trialRepository), TimeSpan.FromDays(7)); // 这里是统一拦截 项目有关的操作允许情况(特殊的地方,比如项目配置(有的在多种状态(初始化,ongoing)都可以操作,有的仅仅在Initializing)还有 项目添加和更新,不走这里,特殊处理,不然在这里显得很乱,判断是哪个接口) - if (trialStatusStr == StaticData.TrialState.TrialOngoing || _trialOptList.Any(t=>t== TrialOpt.BeforeOngoingCantOpt) ) + if (trialStatusStr == StaticData.TrialState.TrialOngoing || _trialOptList.Any(t => t == TrialOpt.BeforeOngoingCantOpt)) { await next.Invoke(); @@ -189,14 +158,14 @@ namespace IRaCIS.Core.Application.Filter // 项目停止、或者完成 不允许操作 else { - //---本次请求被配置规则拦截:项目状态处于进行中时,才允许操作,若此处逻辑有误,请联系开发人员修改 + //---本次请求被配置规则拦截:项目状态处于进行中时,才允许操作,若此处逻辑有误,请联系开发人员修改 context.Result = new JsonResult(ResponseOutput.NotOk(_localizer["TrialResource_InterceptedProjectStatusRule"])); } } //添加项目 签名系统文档的时候 不做拦截 但是更新项目 签名项目文档的时候需要拦截 - else if (_trialOptList.Any(t => t == TrialOpt.AddOrUpdateTrial ||t ==TrialOpt.SignSystemDocNoTrialId)) + else if (_trialOptList.Any(t => t == TrialOpt.AddOrUpdateTrial || t == TrialOpt.SignSystemDocNoTrialId)) { await next.Invoke(); } diff --git a/IRaCIS.Core.Application/Helper/CacheHelper.cs b/IRaCIS.Core.Application/Helper/CacheHelper.cs new file mode 100644 index 000000000..9e0035e9e --- /dev/null +++ b/IRaCIS.Core.Application/Helper/CacheHelper.cs @@ -0,0 +1,27 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace IRaCIS.Core.Application.Helper +{ + + public static class CacheKeys + { + public static string Trial(string trialIdStr) => $"TrialId:{trialIdStr}"; + + + // 你可以为其他实体和模块定义更多的键 + } + + public static class CacheHelper + { + public static async Task GetTrialStatusAsync(Guid trialId, IRepository _trialRepository) + { + var statusStr = await _trialRepository.Where(t => t.Id == trialId, ignoreQueryFilters: true).Select(t => t.TrialStatusStr).FirstOrDefaultAsync(); + + return statusStr; + } + } +} diff --git a/IRaCIS.Core.Application/IRaCIS.Core.Application.xml b/IRaCIS.Core.Application/IRaCIS.Core.Application.xml index 11b44c194..667fa4564 100644 --- a/IRaCIS.Core.Application/IRaCIS.Core.Application.xml +++ b/IRaCIS.Core.Application/IRaCIS.Core.Application.xml @@ -13315,7 +13315,7 @@ - 缓存项目状态 + 缓存项目状态--之前是启动的时候就获取所有的项目进行缓存,加上定时任务刷新,现在的话,改为是按照需要进行缓存请求数据库 diff --git a/IRaCIS.Core.Application/Service/Allocation/DTO/TaskConsistentRuleViewModel.cs b/IRaCIS.Core.Application/Service/Allocation/DTO/TaskConsistentRuleViewModel.cs index 0a566607e..d9470af0a 100644 --- a/IRaCIS.Core.Application/Service/Allocation/DTO/TaskConsistentRuleViewModel.cs +++ b/IRaCIS.Core.Application/Service/Allocation/DTO/TaskConsistentRuleViewModel.cs @@ -33,7 +33,10 @@ namespace IRaCIS.Core.Application.ViewModel public class TaskConsistentRuleBasic : TaskConsistentRuleAddOrEdit { - + /// + /// 任务展示访视 读片任务显示是否顺序 + /// + public ReadingOrder IsReadingTaskViewInOrder { get; set; } = ReadingOrder.InOrder; } public class SubjectGeneratedTask diff --git a/IRaCIS.Core.Application/Service/Allocation/VisitTaskHelpeService.cs b/IRaCIS.Core.Application/Service/Allocation/VisitTaskHelpeService.cs index 72553ebd3..a2b7f630b 100644 --- a/IRaCIS.Core.Application/Service/Allocation/VisitTaskHelpeService.cs +++ b/IRaCIS.Core.Application/Service/Allocation/VisitTaskHelpeService.cs @@ -17,6 +17,7 @@ using IRaCIS.Core.Infra.EFCore.Common; using System.Linq.Expressions; using IRaCIS.Core.Domain.Share.Reading; using IRaCIS.Core.Application.Service.Reading.Dto; +using System.Runtime.InteropServices; namespace IRaCIS.Core.Application.Service { @@ -26,7 +27,7 @@ namespace IRaCIS.Core.Application.Service /// 访视读片任务 /// [ApiExplorerSettings(GroupName = "Trial")] - public class VisitTaskHelpeService : IVisitTaskHelpeService + public class VisitTaskHelpeService : BaseService, IVisitTaskHelpeService { private readonly IRepository _visitTaskRepository; @@ -450,6 +451,19 @@ namespace IRaCIS.Core.Application.Service } + /// + /// 获取GetIsClinicalDataSignTest + /// + /// + /// + public async Task GetIsClinicalDataSignTest(Guid visitTask) + { + var taskinfo = await _visitTaskRepository.Where(x => x.Id == visitTask).FirstNotNullAsync(); + var clinicalDataConfirmList = _trialClinicalDataSetRepository.Where(t => t.TrialId == taskinfo.TrialId && t.IsConfirm).Include(t => t.TrialClinicalDataSetCriteriaList).ToList(); + + Guid readingid = taskinfo.SourceSubjectVisitId == null ? taskinfo.SouceReadModuleId!.Value : taskinfo.SourceSubjectVisitId.Value; + return IsClinicalDataSign(taskinfo.ReadingCategory, taskinfo.VisitTaskNum == 0m, taskinfo.TrialReadingCriterionId, clinicalDataConfirmList, readingid, taskinfo.TrialId); ; + } // 有可能在任务生成之前 就签名完了临床数据 private bool IsClinicalDataSign(ReadingCategory readingCategory, bool isbaseLine, Guid trialReadingCriterionId, List trialClinicalDataSetList, Guid readingId, Guid trialId) @@ -468,7 +482,9 @@ namespace IRaCIS.Core.Application.Service //CRC 的自动签名 不用管 只用处理PM的就好 var haveSignedCount = _readingClinicalDataRepository - .Where(t => t.TrialId == trialId && t.IsSign && t.ReadingClinicalDataState == ReadingClinicalDataStatus.HaveSigned && t.ReadingId == readingId && t.ClinicalDataTrialSet.UploadRole == UploadRole.PM).Count(); + .Where(t => t.TrialId == trialId && t.IsSign + && t.ClinicalDataTrialSet.TrialClinicalDataSetCriteriaList.Any(x=>x.TrialReadingCriterionId== trialReadingCriterionId) + && t.ReadingClinicalDataState == ReadingClinicalDataStatus.HaveSigned && t.ReadingId == readingId && t.ClinicalDataTrialSet.UploadRole == UploadRole.PM).Count(); var readModule = _readModuleRepository.Where(t => t.Id == readingId).FirstOrDefault(); @@ -1415,6 +1431,7 @@ namespace IRaCIS.Core.Application.Service case GenerateTaskCategory.SelfConsistent: var readingCriterionId = generateTaskCommand.GenerataConsistentTaskList.First().TrialReadingCriterionId; + var isReadingTaskViewInOrder = await _trialReadingCriterionRepository.Where(t => t.Id == readingCriterionId).Select(x => x.IsReadingTaskViewInOrder).FirstNotNullAsync(); var subjectId = generateTaskCommand.GenerataConsistentTaskList.First().SubjectId; //var trialReadingCriterion=_trialReadingCriterionRepository.Where(t=>t.Id== trialReadingCriterionId).FirstOrDefault(); @@ -1457,7 +1474,11 @@ namespace IRaCIS.Core.Application.Service foreach (var task in generateTaskCommand.GenerataConsistentTaskList) { - var exsitPDF = await _readingClinicalDataRepository.AnyAsync(t => t.TrialId == trialId && + + + var exsitPDF = await _readingClinicalDataRepository + .WhereIf(isReadingTaskViewInOrder== ReadingOrder.Random,t=>t.ReadingId== task.SouceReadModuleId|| t.ReadingId == task.SourceSubjectVisitId) + .AnyAsync(t => t.TrialId == trialId && t.SubjectId== task.SubjectId&& t.ClinicalDataTrialSet.TrialClinicalDataSetCriteriaList.Any(c => c.TrialReadingCriterionId == readingCriterionId) diff --git a/IRaCIS.Core.Application/Service/Allocation/_MapConfig.cs b/IRaCIS.Core.Application/Service/Allocation/_MapConfig.cs index 00dc9b3ef..f56b27d40 100644 --- a/IRaCIS.Core.Application/Service/Allocation/_MapConfig.cs +++ b/IRaCIS.Core.Application/Service/Allocation/_MapConfig.cs @@ -293,7 +293,8 @@ namespace IRaCIS.Core.Application.Service //CreateMap() // .ForMember(o => o.GeneratedSubjectCount, t => t.MapFrom(u => u.DoctorVisitTaskList.Where(t => t.IsAnalysisCreate && t.TaskConsistentRuleId == u.Id).Select(t => t.SubjectId).Distinct().Count())) ; - CreateMap(); + CreateMap() + .ForMember(o => o.IsReadingTaskViewInOrder, t => t.MapFrom(u => u.TrialReadingCriterion.IsReadingTaskViewInOrder)); CreateMap(); diff --git a/IRaCIS.Core.Application/Service/SiteSurvey/TrialSiteSurveyService.cs b/IRaCIS.Core.Application/Service/SiteSurvey/TrialSiteSurveyService.cs index 2665746ff..5affbbd80 100644 --- a/IRaCIS.Core.Application/Service/SiteSurvey/TrialSiteSurveyService.cs +++ b/IRaCIS.Core.Application/Service/SiteSurvey/TrialSiteSurveyService.cs @@ -398,7 +398,7 @@ namespace IRaCIS.Core.Application.Contracts var result = await _trialSiteSurveyRepository.Where(t => t.Id == trialSiteSurveyId && t.TrialId == trialId).IgnoreQueryFilters() .ProjectTo(_mapper.ConfigurationProvider, new { isEn_Us = _userInfo.IsEn_Us }).FirstOrDefaultAsync().IfNullThrowException(); - var siteSurveryConfig = _trialSiteSurveyRepository.Where(t => t.Id == trialSiteSurveyId).Select(t => t.Trial.TrialExtraConfigJsonStr).FirstOrDefault()??string.Empty; + var siteSurveryConfig = _trialSiteSurveyRepository.Where(t => t.Id == trialSiteSurveyId).IgnoreQueryFilters().Select(t => t.Trial.TrialExtraConfigJsonStr).FirstOrDefault()??string.Empty; result.SiteSurveyFiledConfig = JsonConvert.DeserializeObject(siteSurveryConfig) ?? new TrialExtraConfig(); return result; diff --git a/IRaCIS.Core.Application/Service/TrialSiteUser/TrialConfigService.cs b/IRaCIS.Core.Application/Service/TrialSiteUser/TrialConfigService.cs index b130638a7..f80656e8f 100644 --- a/IRaCIS.Core.Application/Service/TrialSiteUser/TrialConfigService.cs +++ b/IRaCIS.Core.Application/Service/TrialSiteUser/TrialConfigService.cs @@ -23,6 +23,8 @@ using IRaCIS.Application.Contracts; using SixLabors.ImageSharp.Formats.Tiff.Compression.Decompressors; using Newtonsoft.Json; using Microsoft.Extensions.Options; +using IRaCIS.Core.Application.Helper; +using ZiggyCreatures.Caching.Fusion; namespace IRaCIS.Core.Application { @@ -1239,8 +1241,8 @@ namespace IRaCIS.Core.Application } - await _provider.SetAsync(trialId.ToString(), trialStatusStr, TimeSpan.FromDays(7)); - + await _fusionCache.SetAsync(CacheKeys.Trial(trial.Id.ToString()), trialStatusStr, TimeSpan.FromDays(7)); + await _repository.SaveChangesAsync(); return ResponseOutput.Ok(); @@ -1390,7 +1392,7 @@ namespace IRaCIS.Core.Application { var trialCode = await _trialRepository.Where(t => t.Id == trialId).Select(t => t.TrialCode).FirstOrDefaultAsync(); - return new TrialPacsInfo() { Ip=optionsMonitor.CurrentValue.IP,Port=optionsMonitor.CurrentValue.Port,TrialCalledAE=$"EI{trialCode}" }; + return new TrialPacsInfo() { Ip = optionsMonitor.CurrentValue.IP, Port = optionsMonitor.CurrentValue.Port, TrialCalledAE = $"EI{trialCode}" }; } } } diff --git a/IRaCIS.Core.Application/Service/TrialSiteUser/TrialService.cs b/IRaCIS.Core.Application/Service/TrialSiteUser/TrialService.cs index 190511173..7534c3860 100644 --- a/IRaCIS.Core.Application/Service/TrialSiteUser/TrialService.cs +++ b/IRaCIS.Core.Application/Service/TrialSiteUser/TrialService.cs @@ -12,6 +12,8 @@ using Microsoft.AspNetCore.Authorization; using System.Linq.Expressions; using System.Linq; using IRaCIS.Core.Domain.Models; +using IRaCIS.Core.Application.Helper; +using ZiggyCreatures.Caching.Fusion; namespace IRaCIS.Application.Services { @@ -93,7 +95,7 @@ namespace IRaCIS.Application.Services .WhereIf(multiCriteriaSelectCount > 0, t => t.TrialDicList.Count(t => t.KeyName == StaticData.Criterion) == multiCriteriaSelectCount) .WhereIf(multiReviewTypeSelectCount > 0, t => t.TrialDicList.Count(t => t.KeyName == StaticData.ReviewType) == multiReviewTypeSelectCount) .WhereIf(_userInfo.UserTypeEnumInt != (int)UserTypeEnum.SuperAdmin, t => t.TrialUserList.Any(t => t.UserId == _userInfo.Id && t.IsDeleted == false) && t.IsDeleted == false) - .ProjectTo(_mapper.ConfigurationProvider, new { userTypeEnumInt = _userInfo.UserTypeEnumInt, userId = _userInfo.Id , isEn_Us= _userInfo.IsEn_Us }); + .ProjectTo(_mapper.ConfigurationProvider, new { userTypeEnumInt = _userInfo.UserTypeEnumInt, userId = _userInfo.Id, isEn_Us = _userInfo.IsEn_Us }); return await query.ToPagedListAsync(searchParam.PageIndex, searchParam.PageSize, string.IsNullOrWhiteSpace(searchParam.SortField) ? "CreateTime" : searchParam.SortField, searchParam.Asc); @@ -119,7 +121,7 @@ namespace IRaCIS.Application.Services [HttpGet("{projectId:guid}")] public async Task GetTrialInfoAndLockState(Guid projectId) { - return (await _trialRepository.Where(o => o.Id == projectId).ProjectTo(_mapper.ConfigurationProvider, new {isEn_Us = _userInfo.IsEn_Us }).FirstOrDefaultAsync()).IfNullThrowException(); + return (await _trialRepository.Where(o => o.Id == projectId).ProjectTo(_mapper.ConfigurationProvider, new { isEn_Us = _userInfo.IsEn_Us }).FirstOrDefaultAsync()).IfNullThrowException(); } @@ -216,7 +218,7 @@ namespace IRaCIS.Application.Services await _repository.AddAsync(new TrialPaymentPrice() { TrialId = trial.Id }); //添加访视 - await _repository.AddAsync(new VisitStage { TrialId = trial.Id, VisitNum = 0, BlindName = "B" + 0.ToString("D3"), VisitDay = 0, VisitName = "Baseline", IsBaseLine = true,VisitWindowLeft=-28,VisitWindowRight=0 }); + await _repository.AddAsync(new VisitStage { TrialId = trial.Id, VisitNum = 0, BlindName = "B" + 0.ToString("D3"), VisitDay = 0, VisitName = "Baseline", IsBaseLine = true, VisitWindowLeft = -28, VisitWindowRight = 0 }); await _repository.AddAsync(new VisitStage { TrialId = trial.Id, VisitNum = 1, BlindName = "B" + 10.ToString("D3"), VisitDay = 30, VisitName = "Visit 1", VisitWindowLeft = -5, VisitWindowRight = 5 }); @@ -234,12 +236,11 @@ namespace IRaCIS.Application.Services { item.TrialId = trial.Id; } - - - await _repository.AddRangeAsync(needAddBodyPartList,true); - _provider.Set(trial.Id.ToString(), StaticData.TrialState.TrialInitializing, TimeSpan.FromDays(7)); + await _repository.AddRangeAsync(needAddBodyPartList, true); + + await _fusionCache.SetAsync(CacheKeys.Trial(trial.Id.ToString()), StaticData.TrialState.TrialInitializing, TimeSpan.FromDays(7)); return ResponseOutput.Ok(trial); } @@ -589,7 +590,7 @@ namespace IRaCIS.Application.Services await _repository.BatchDeleteAsync(t => t.OriginalReReadingTask.TrialId == trialId); await _repository.BatchDeleteAsync(t => t.TrialId == trialId); - await _repository.BatchDeleteAsync(t => t.TrialId == trialId) ; + await _repository.BatchDeleteAsync(t => t.TrialId == trialId); return ResponseOutput.Ok(); @@ -650,7 +651,7 @@ namespace IRaCIS.Application.Services .WhereIf(!string.IsNullOrEmpty(searchModel.Code), o => o.TrialCode.Contains(searchModel.Code)) .WhereIf(!string.IsNullOrWhiteSpace(searchModel.Indication), o => o.Indication.Contains(searchModel.Indication)) .WhereIf(_userInfo.UserTypeEnumInt != (int)UserTypeEnum.SuperAdmin, t => t.TrialUserList.Any(t => t.UserId == _userInfo.Id)) - .ProjectTo(_mapper.ConfigurationProvider, new { userTypeEnumInt = _userInfo.UserTypeEnumInt, userId = _userInfo.Id ,isEn_Us = _userInfo.IsEn_Us }); + .ProjectTo(_mapper.ConfigurationProvider, new { userTypeEnumInt = _userInfo.UserTypeEnumInt, userId = _userInfo.Id, isEn_Us = _userInfo.IsEn_Us }); return await query.ToPagedListAsync(searchModel.PageIndex, searchModel.PageSize, string.IsNullOrWhiteSpace(searchModel.SortField) ? "CreateTime" : searchModel.SortField, searchModel.Asc); diff --git a/IRaCIS.Core.Application/Service/Visit/PatientService.cs b/IRaCIS.Core.Application/Service/Visit/PatientService.cs index cea8434bb..dce64507d 100644 --- a/IRaCIS.Core.Application/Service/Visit/PatientService.cs +++ b/IRaCIS.Core.Application/Service/Visit/PatientService.cs @@ -340,6 +340,7 @@ namespace IRaCIS.Application.Services foreach (var waitUploadItem in scpStudyList) { + if (isVerifyVisitImageDate) { //小于当前访视 最近的最晚拍片 @@ -349,7 +350,8 @@ namespace IRaCIS.Application.Services { // $"当前访视检查时间{waitUploadItem.StudyDate?.ToString("yyyy-MM-dd")}不能早于前序访视检查时间{before?.ToString("yyyy-MM-dd")},请核对检查数据是否有误", - result.Add(new VerifySCPStudyUploadResult() { ErrorMesseage = _localizer["Study_VisitBeforePrevError", waitUploadItem.StudyDate?.ToString("yyyy-MM-dd")!, before?.ToString("yyyy-MM-dd")!] }); + result.Add(new VerifySCPStudyUploadResult() { SCPStudyId = waitUploadItem.Id, ErrorMesseage = _localizer["Study_VisitBeforePrevError", waitUploadItem.StudyDate?.ToString("yyyy-MM-dd")!, before?.ToString("yyyy-MM-dd")!] }); + continue; // 跳过当前迭代 } //大于当前访视 最近的最早拍片日期 @@ -358,13 +360,15 @@ namespace IRaCIS.Application.Services if (after != null && waitUploadItem.StudyDate != null && after < waitUploadItem.StudyDate) { // $"当前访视检查时间{waitUploadItem.StudyDate?.ToString("yyyy-MM-dd")}不能晚于该访视之后的检查时间{after?.ToString("yyyy-MM-dd")},请核对检查数据是否有误" - result.Add(new VerifySCPStudyUploadResult() { ErrorMesseage = _localizer["Study_VisitAfterSubseqError", waitUploadItem.StudyDate?.ToString("yyyy-MM-dd")!, after?.ToString("yyyy-MM-dd")!]}); + result.Add(new VerifySCPStudyUploadResult() { SCPStudyId = waitUploadItem.Id, ErrorMesseage = _localizer["Study_VisitAfterSubseqError", waitUploadItem.StudyDate?.ToString("yyyy-MM-dd")!, after?.ToString("yyyy-MM-dd")!] }); + continue; // 跳过当前迭代 } } var verifyStudyInfo = _repository.Where(t => t.TrialId == trialId && t.Id == waitUploadItem.Id).ProjectTo(_mapper.ConfigurationProvider).FirstOrDefault(); - var currentStudyResult = new VerifyStudyUploadResult(); + var currentStudyResult = new VerifySCPStudyUploadResult() { SCPStudyId = waitUploadItem.Id }; + //数据库不存在该检查 允许上传 if (verifyStudyInfo == null) @@ -391,6 +395,8 @@ namespace IRaCIS.Application.Services currentStudyResult.ErrorMesseage = _localizer["Study_ImgAlreadyUploaded", verifyStudyInfo.SubjectCode, verifyStudyInfo.VisitName]; } } + + result.Add(currentStudyResult); } @@ -413,7 +419,7 @@ namespace IRaCIS.Application.Services [UnitOfWork] [TypeFilter(typeof(TrialResourceFilter), Arguments = new object[] { "AfterStopCannNotOpt" })] public async Task SubmitVisitStudyBinding(SubmitVisitStudyBindingCommand inCommand, - [FromServices]IRepository _dicomstudyRepository, + [FromServices] IRepository _dicomstudyRepository, [FromServices] IRepository _dicomSeriesRepository, [FromServices] IRepository _dicomInstanceRepository) { @@ -427,7 +433,7 @@ namespace IRaCIS.Application.Services var allowUploadList = verifyResult.Where(u => u.AllowUpload == true).Select(t => t.SCPStudyId).ToList(); var allowReUploadList = verifyResult.Where(u => u.AllowReUpload == true).Select(t => t.SCPStudyId).ToList(); - if (inCommand.SCPStudyIdList.All(t => allowUploadList.Contains(t)) && inCommand.ReUploadSCPStudyIdList.All(t => allowReUploadList.Contains(t))) + if (!(inCommand.SCPStudyIdList.All(t => allowUploadList.Contains(t)) && inCommand.ReUploadSCPStudyIdList.All(t => allowReUploadList.Contains(t)))) { throw new BusinessValidationFailedException("对接提示: 前端提交的检查有不能上传的,请刷新页面调用验证接口重试!"); } @@ -505,7 +511,7 @@ namespace IRaCIS.Application.Services var instanceIdList = _dicomInstanceRepository.Where(t => t.Id == scpStudyId).Select(t => t.Id).ToList(); - var scpStudy = _scpStudyRepository.Where(t => t.Id == scpStudyId).Include(t=>t.SeriesList).ThenInclude(t=>t.SCPInstanceList).FirstOrDefault(); + var scpStudy = _scpStudyRepository.Where(t => t.Id == scpStudyId).Include(t => t.SeriesList).ThenInclude(t => t.SCPInstanceList).FirstOrDefault(); //以最后一次为准 study.IsFromPACS = true; diff --git a/IRaCIS.Core.Infrastructure/_IRaCIS/_Config/_StaticData.cs b/IRaCIS.Core.Infrastructure/_IRaCIS/_Config/_StaticData.cs index 42ab4a9ca..79ccfa568 100644 --- a/IRaCIS.Core.Infrastructure/_IRaCIS/_Config/_StaticData.cs +++ b/IRaCIS.Core.Infrastructure/_IRaCIS/_Config/_StaticData.cs @@ -15,6 +15,7 @@ public static class StaticData public static Dictionary Log_Locoalize_Dic = new Dictionary(); + #region 国际化 public static readonly string En_US_Json = "en-US.json"; public static readonly string Zh_CN_Json = "zh-CN.json"; @@ -70,9 +71,11 @@ public static class StaticData } + #endregion - #region 字典表项固定值 - public static readonly string Title = "Title"; + #region 字典表项固定值 + + public static readonly string Title = "Title"; public static readonly string ReadingType = "ReadingType"; public static readonly string Subspeciality = "Subspeciality"; @@ -80,6 +83,7 @@ public static class StaticData public static readonly string Criterion = "Criterion"; public static readonly string ReviewType = "ReviewType"; public static readonly string ReadingStandard = "ReadingStandard"; + #endregion