From 0006f1215162e581759b37a29db2d18d46d536ed Mon Sep 17 00:00:00 2001 From: hang <872297557@qq.com> Date: Wed, 23 Aug 2023 17:49:06 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E5=AE=9A=E6=97=B6=E4=BB=BB?= =?UTF-8?q?=E5=8A=A1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- IRaCIS.Core.API/Program.cs | 23 +- .../_PipelineExtensions/HangfireConfig.cs | 4 + .../_ServiceExtensions/QuartZSetup.cs | 24 +-- .../_ServiceExtensions/hangfireSetup.cs | 8 +- IRaCIS.Core.API/appsettings.Test_Study.json | 7 +- IRaCIS.Core.API/appsettings.Uat_Study.json | 3 +- .../EmailTemplate/TrialDoctorExistJoin.html | 1 - .../CacheTrialStatusQuartZJob.cs | 72 ------- .../BackGroundJob/IRaCISCHangfireJob.cs | 197 ++++++++++++++++++ .../BackGroundJob/IRaCISCacheHangfireJob.cs | 99 --------- .../IRaCIS.Core.Application.xml | 6 + 11 files changed, 236 insertions(+), 208 deletions(-) delete mode 100644 IRaCIS.Core.Application/BackGroundJob/CacheTrialStatusQuartZJob.cs create mode 100644 IRaCIS.Core.Application/BackGroundJob/IRaCISCHangfireJob.cs delete mode 100644 IRaCIS.Core.Application/BackGroundJob/IRaCISCacheHangfireJob.cs diff --git a/IRaCIS.Core.API/Program.cs b/IRaCIS.Core.API/Program.cs index b771b7a5f..cd37383b2 100644 --- a/IRaCIS.Core.API/Program.cs +++ b/IRaCIS.Core.API/Program.cs @@ -13,6 +13,8 @@ using System.IO; using IRaCIS.Core.Domain.Share; using IRaCIS.Core.Infra.EFCore; using IRaCIS.Core.Application.Helper; +using IRaCIS.Application.Services.BackGroundJob; +using Hangfire; namespace IRaCIS.Core.API { @@ -59,17 +61,10 @@ namespace IRaCIS.Core.API Log.Logger.Warning($"当前环境:{enviromentName}"); - NewId.SetProcessIdProvider(new CurrentProcessIdProvider()); - - //缓存项目的状态 匿名化数据 - await InitCache(host); - - - - - + ////缓存项目的状态 匿名化数据 + //await InitCache(host); host.Run(); @@ -107,15 +102,7 @@ namespace IRaCIS.Core.API var _repository = host.Services.GetService(typeof(IRepository)) as IRepository; //初始化 国际化数据,并且监测国际化文件变更 - await InternationalizationHelper.InitInternationlizationDataAndWatchJsonFileAsync(_repository); - - var _mediator = host.Services.GetService(typeof(IMediator)) as IMediator; - - await _mediator.Send(new AnonymizeCacheRequest()); - - await _mediator.Send(new TrialStateCacheRequest()); - - + //await InternationalizationHelper.InitInternationlizationDataAndWatchJsonFileAsync(_repository); } diff --git a/IRaCIS.Core.API/_PipelineExtensions/HangfireConfig.cs b/IRaCIS.Core.API/_PipelineExtensions/HangfireConfig.cs index f0834570d..7c9b5610a 100644 --- a/IRaCIS.Core.API/_PipelineExtensions/HangfireConfig.cs +++ b/IRaCIS.Core.API/_PipelineExtensions/HangfireConfig.cs @@ -3,6 +3,7 @@ using Hangfire.Dashboard; using Hangfire.Dashboard.BasicAuthorization; using IRaCIS.Application.Services.BackGroundJob; using IRaCIS.Core.API.Filter; +using IRaCIS.Core.Application.Helper; using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Hosting; @@ -43,6 +44,9 @@ namespace IRaCIS.Core.API }); #region hangfire + + HangfireJobHelper.ImmediatelyOnceOnlyJob( t => t.InitHangfireJobTaskAsync() ); + //// 寤惰繜浠诲姟鎵ц 1绉掍箣鍚庢墽琛 鏈夋椂鍚姩娌¤繍琛 鎹㈡垚娣诲姞鍒伴槦鍒椾腑 //BackgroundJob.Schedule(t => t.MemoryCacheTrialStatus(), TimeSpan.FromSeconds(1)); diff --git a/IRaCIS.Core.API/_ServiceExtensions/QuartZSetup.cs b/IRaCIS.Core.API/_ServiceExtensions/QuartZSetup.cs index a7f602d85..9ba331369 100644 --- a/IRaCIS.Core.API/_ServiceExtensions/QuartZSetup.cs +++ b/IRaCIS.Core.API/_ServiceExtensions/QuartZSetup.cs @@ -6,11 +6,10 @@ using Quartz; namespace IRaCIS.Core.API { - public static class QuartZSetup + public static class QuartZSetup { public static void AddQuartZSetup(this IServiceCollection services, IConfiguration configuration) { - services.AddTransient(); services.AddTransient(); services.AddQuartz(q => @@ -21,16 +20,17 @@ namespace IRaCIS.Core.API q.UseMicrosoftDependencyInjectionJobFactory(); // 鍩烘湰Quartz璋冨害鍣ㄣ佷綔涓氬拰瑙﹀彂鍣ㄩ厤缃 - var jobKey = new JobKey("RegularTrialWork", "regularWorkGroup"); - q.AddJob(jobKey, j => j - .WithDescription("Trial regular work") - ); - q.AddTrigger(t => t - .WithIdentity("TrialStatusTrigger") - .ForJob(jobKey) - .WithCronSchedule("0 0 * * * ?") - .WithDescription("My regular trial work trigger") - ); + //var jobKey = new JobKey("RegularTrialWork", "regularWorkGroup"); + //q.AddJob(jobKey, j => j + // .WithDescription("Trial regular work") + //); + + //q.AddTrigger(t => t + // .WithIdentity("TrialStatusTrigger") + // .ForJob(jobKey) + // .WithCronSchedule("0 0 * * * ?") + // .WithDescription("My regular trial work trigger") + //); diff --git a/IRaCIS.Core.API/_ServiceExtensions/hangfireSetup.cs b/IRaCIS.Core.API/_ServiceExtensions/hangfireSetup.cs index b3b02c3f9..e246d42c2 100644 --- a/IRaCIS.Core.API/_ServiceExtensions/hangfireSetup.cs +++ b/IRaCIS.Core.API/_ServiceExtensions/hangfireSetup.cs @@ -20,7 +20,7 @@ namespace IRaCIS.Core.API //鎸囧畾瀛樺偍浠嬭川 hangFireConfig.UseSqlServerStorage(hangFireConnStr, new SqlServerStorageOptions() { - SchemaName = "hangfire", + SchemaName = "dbo", CommandBatchMaxTimeout = TimeSpan.FromMinutes(5), SlidingInvisibilityTimeout = TimeSpan.FromMinutes(5), QueuePollInterval = TimeSpan.Zero, @@ -33,7 +33,11 @@ namespace IRaCIS.Core.API }); - services.AddHangfireServer(); + services.AddHangfireServer(option => + { + option.ServerName = "test_study"; + option.Queues = new[] { "immediately_once","default" }; + }); } } diff --git a/IRaCIS.Core.API/appsettings.Test_Study.json b/IRaCIS.Core.API/appsettings.Test_Study.json index 0e06899ff..fff5a9b8e 100644 --- a/IRaCIS.Core.API/appsettings.Test_Study.json +++ b/IRaCIS.Core.API/appsettings.Test_Study.json @@ -22,8 +22,7 @@ "LoginMaxFailCount": 5, "LoginFailLockMinutes": 30 - - + }, "SystemEmailSendConfig": { @@ -31,7 +30,9 @@ "Host": "smtp.qiye.aliyun.com", "FromEmail": "test-study@extimaging.com", "FromName": "Test_Study", - "AuthorizationCode": "zhanying123" + "AuthorizationCode": "zhanying123", + + "SiteUrl": "http://test.study.extimaging.com/login" } } diff --git a/IRaCIS.Core.API/appsettings.Uat_Study.json b/IRaCIS.Core.API/appsettings.Uat_Study.json index e3d31bacb..7793be29a 100644 --- a/IRaCIS.Core.API/appsettings.Uat_Study.json +++ b/IRaCIS.Core.API/appsettings.Uat_Study.json @@ -31,7 +31,8 @@ "Host": "smtp.qiye.aliyun.com", "FromEmail": "uat-study@extimaging.com", "FromName": "Uat_Study", - "AuthorizationCode": "zhanying123" + "AuthorizationCode": "zhanying123", + "SiteUrl": "http://uat.study.extimaging.com/login" } } diff --git a/IRaCIS.Core.API/wwwroot/EmailTemplate/TrialDoctorExistJoin.html b/IRaCIS.Core.API/wwwroot/EmailTemplate/TrialDoctorExistJoin.html index 8ae645e3b..8686d015e 100644 --- a/IRaCIS.Core.API/wwwroot/EmailTemplate/TrialDoctorExistJoin.html +++ b/IRaCIS.Core.API/wwwroot/EmailTemplate/TrialDoctorExistJoin.html @@ -38,7 +38,6 @@ -
绁濇偍椤哄埄锛/Best Regards
灞曞奖鍖荤枟
diff --git a/IRaCIS.Core.Application/BackGroundJob/CacheTrialStatusQuartZJob.cs b/IRaCIS.Core.Application/BackGroundJob/CacheTrialStatusQuartZJob.cs deleted file mode 100644 index e3be27479..000000000 --- a/IRaCIS.Core.Application/BackGroundJob/CacheTrialStatusQuartZJob.cs +++ /dev/null @@ -1,72 +0,0 @@ -锘縰sing System; -using System.Linq; -using System.Threading.Tasks; -using EasyCaching.Core; -using IRaCIS.Core.Domain; -using IRaCIS.Core.Infra.EFCore; -using IRaCIS.Core.Domain.Models; -using Microsoft.Extensions.Logging; -using Quartz; -using IRaCIS.Core.Domain.Share; - -namespace IRaCIS.Application.Services.BackGroundJob -{ - - public class CacheTrialStatusQuartZJob: IJob - { - - private readonly IRepository _trialRepository; - private readonly IEasyCachingProvider _provider; - private readonly ILogger _logger; - private readonly IRepository _systemAnonymizationRepository; - - public CacheTrialStatusQuartZJob(IRepository trialRepository, IEasyCachingProvider provider,ILogger logger, IRepository systemAnonymizationRepository) - { - _trialRepository = trialRepository; - _provider = provider; - _logger = logger; - _systemAnonymizationRepository = systemAnonymizationRepository; - } - - public async Task Execute(IJobExecutionContext context) - - { - _logger.LogInformation($"寮濮嬫墽琛孮uartZ瀹氭椂浠诲姟浣滀笟"); - try - { - await MemoryCacheTrialStatus(); - - await MemoryCacheAnonymizeData(); - - } - catch (Exception e) - { - _logger.LogError($" 鏌ヨ鍜岀紦瀛樿繃绋嬪嚭鐜板紓甯"+e.Message); - } - _logger.LogInformation("QuartZ瀹氭椂浠诲姟浣滀笟缁撴潫"); - } - - - public async Task MemoryCacheTrialStatus() - { - 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)); - } - - - - } -} \ No newline at end of file diff --git a/IRaCIS.Core.Application/BackGroundJob/IRaCISCHangfireJob.cs b/IRaCIS.Core.Application/BackGroundJob/IRaCISCHangfireJob.cs new file mode 100644 index 000000000..348b002de --- /dev/null +++ b/IRaCIS.Core.Application/BackGroundJob/IRaCISCHangfireJob.cs @@ -0,0 +1,197 @@ +锘縰sing EasyCaching.Core; +using Hangfire; +using IRaCIS.Core.Application.Helper; +using IRaCIS.Core.Application.Service; +using IRaCIS.Core.Domain.Share; +using IRaCIS.Core.Infrastructure; +using Microsoft.EntityFrameworkCore.SqlServer.Query.Internal; +using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.Logging; +using Newtonsoft.Json; + +namespace IRaCIS.Application.Services.BackGroundJob +{ + + public interface IIRaCISHangfireJob + { + + Task MemoryCacheTrialStatusAsync(); + + Task InitHangfireJobTaskAsync(); + + } + public class IRaCISCHangfireJob : 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 _trialEmailNoticeConfigRepository; + private readonly IRepository _internationalizationRepository; + + + + public IRaCISCHangfireJob(IRepository trialRepository, ILogger logger, IEasyCachingProvider provider, IRepository trialEmailNoticeConfigRepository, IRepository internationalizationRepository) + { + _trialRepository = trialRepository; + _provider = provider; + _logger = logger; + _trialEmailNoticeConfigRepository = trialEmailNoticeConfigRepository; + _internationalizationRepository = internationalizationRepository; + } + + public async Task InitHangfireJobTaskAsync() + { + _logger.LogInformation("椤圭洰鍚姩 hangfire 浠诲姟鍒濆鍖 鎵ц寮濮媬"); + + + //椤圭洰鐘舵 绔嬪嵆鍔犺浇鍒扮紦瀛樹腑 + await MemoryCacheTrialStatusAsync(); + + + //鍒涘缓椤圭洰缂撳瓨 瀹氭椂浠诲姟 + HangfireJobHelper.AddOrUpdateInitCronJob("RecurringJob_Cache_TrialState", t => t.MemoryCacheTrialStatusAsync(), Cron.Daily()); + + //鍒濆鍖 + + await InitInternationlizationDataAndWatchJsonFileAsync(); + + //鍒涘缓閭欢瀹氭椂浠诲姟 + + await InitSysAndTrialCronJobAsync(); + + + _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))); + + } + + + #region 鍥介檯鍖 鍒濆鍖 + + + public async Task InitInternationlizationDataAndWatchJsonFileAsync() + { + //鏌ヨ鏁版嵁搴撶殑鏁版嵁 + var toJsonList = await _internationalizationRepository.Where(t => t.InternationalizationType == 1).Select(t => new + { + t.Code, + t.Value, + t.ValueCN + }).ToListAsync(); + + //缁勭粐鎴恓son 鏂囦欢 + + var usJsonPath = Path.Combine(JsonFileFolder, StaticData.En_US_Json); + var cnJsonPath = Path.Combine(JsonFileFolder, StaticData.Zh_CN_Json); + + + //鏈湴闈欐佹枃浠跺浗闄呭寲闇瑕 + foreach (var tojsonItem in toJsonList) + { + StaticData.En_US_Dic[tojsonItem.Code] = tojsonItem.Value; + StaticData.Zh_CN_Dic[tojsonItem.Code] = tojsonItem.ValueCN; + } + + File.WriteAllText(usJsonPath, JsonConvert.SerializeObject(StaticData.En_US_Dic)); + File.WriteAllText(cnJsonPath, JsonConvert.SerializeObject(StaticData.Zh_CN_Dic)); + + + //鐩戞祴Json鏂囦欢鍙樻洿 瀹炴椂鍒锋柊鏁版嵁 + WatchJsonFile(usJsonPath); + WatchJsonFile(cnJsonPath); + + } + + public void WatchJsonFile(string filePath) + { + if (!File.Exists(filePath)) + { + throw new BusinessValidationFailedException("鍥介檯鍖朖son鏂囦欢涓嶅瓨鍦"); + } + + FileSystemWatcher watcher = new FileSystemWatcher(Path.GetDirectoryName(filePath), Path.GetFileName(filePath)); + watcher.Changed += (sender, e) => LoadJsonFile(filePath); + watcher.EnableRaisingEvents = true; + + } + + + private void LoadJsonFile(string filePath) + { + + IConfigurationBuilder builder = new ConfigurationBuilder().AddJsonFile(filePath); + + IConfigurationRoot enConfiguration = builder.Build(); + + foreach (IConfigurationSection section in enConfiguration.GetChildren()) + { + if (filePath.Contains(StaticData.En_US_Json)) + { + StaticData.En_US_Dic[section.Key] = section.Value; + + } + else + { + StaticData.Zh_CN_Dic[section.Key] = section.Value; + } + } + } + + #endregion + + public async Task InitSysAndTrialCronJobAsync() + { + var taskInfoList = await _trialEmailNoticeConfigRepository.Where(t => t.Trial.TrialStatusStr == StaticData.TrialState.TrialOngoing && t.EmailCron != string.Empty) + .Select(t => new { t.Id, t.Code, t.EmailCron, t.BusinessScenarioEnum, t.TrialId }) + .ToListAsync(); + + + foreach (var task in taskInfoList) + { + //鍒╃敤涓婚敭浣滀负浠诲姟Id + var jobId = task.Id.ToString(); + switch (task.BusinessScenarioEnum) + { + + case CommonDocumentBusinessScenario.QCTask: + HangfireJobHelper.AddOrUpdateCronJob(jobId, t => t.SendTrialImageQCTaskEmailAsync(task.TrialId), task.EmailCron, task.Code); + break; + case CommonDocumentBusinessScenario.QCQuestion: + HangfireJobHelper.AddOrUpdateCronJob(jobId, t => t.SendTrialQCQuestionEmailAsync(task.TrialId), task.EmailCron, task.Code); + break; + case CommonDocumentBusinessScenario.ImageQuestion: + HangfireJobHelper.AddOrUpdateCronJob(jobId, t => t.SendTrialImageQuestionAsync(task.TrialId), task.EmailCron, task.Code); + break; + + //case CommonDocumentBusinessScenario.EnrollConfirmed: + // AddOrUpdateCronJob(jobId, task.Code, t => t.SendClinicalDataQuestionAsync(), task.EmailCron); + // break; + //case CommonDocumentBusinessScenario.PDConfirmed: + // break; + //case CommonDocumentBusinessScenario.ClinicalDataQuestion: + // break; + default: + break; + } + + } + } + + + } +} \ No newline at end of file diff --git a/IRaCIS.Core.Application/BackGroundJob/IRaCISCacheHangfireJob.cs b/IRaCIS.Core.Application/BackGroundJob/IRaCISCacheHangfireJob.cs deleted file mode 100644 index 80a3d16ac..000000000 --- a/IRaCIS.Core.Application/BackGroundJob/IRaCISCacheHangfireJob.cs +++ /dev/null @@ -1,99 +0,0 @@ -锘縰sing EasyCaching.Core; -using IRaCIS.Core.Domain.Share; -using Microsoft.EntityFrameworkCore.SqlServer.Query.Internal; -using Microsoft.Extensions.Logging; - -namespace IRaCIS.Application.Services.BackGroundJob -{ - - public interface IIRaCISCacheHangfireJob - { - - Task ProjectStartCache(); - Task MemoryCacheTrialStatus(); - - Task MemoryCacheAnonymizeData(); - - Task CacheUserTypePermission(Guid? cacheUserTypeId); - } - public class IRaCISCacheHangfireJob: IIRaCISCacheHangfireJob - { - private readonly IRepository _trialRepository; - private readonly IEasyCachingProvider _provider; - private readonly ILogger _logger; - private readonly IRepository _systemAnonymizationRepository; - - 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 ProjectStartCache() - { - _logger.LogInformation("hangfire 瀹氭椂缂撳瓨椤圭洰鐘舵佷换鍔″紑濮媬"); - try - { - await MemoryCacheTrialStatus(); - - await MemoryCacheAnonymizeData(); - - await CacheUserTypePermission(); - } - catch (Exception e) - { - _logger.LogError("hangfire 瀹氭椂浠诲姟鎵ц澶辫触" + e.Message); - - } - - _logger.LogInformation("hangfire 瀹氭椂浠诲姟鎵ц缁撴潫"); - } - - public async Task MemoryCacheTrialStatus() - { - 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)); - } - - 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 9fe3eb400..fdaf9fd35 100644 --- a/IRaCIS.Core.Application/IRaCIS.Core.Application.xml +++ b/IRaCIS.Core.Application/IRaCIS.Core.Application.xml @@ -11000,6 +11000,12 @@ 鏋勯犲嚱鏁版敞鍏 + + + 缂撳瓨椤圭洰鐘舵 + + + 缁熶竴杩斿洖鍓嶇鏁版嵁鍖呰锛屼箣鍓嶅湪鎺у埗鍣ㄥ寘瑁咃紝鐜板湪淇敼涓哄姩鎬丄pi 鍦≧esultFilter杩欓噷鍖呰锛屽噺灏戦噸澶嶅啑浣欎唬鐮