From 498c02431b4d41d101b027e11228fac947a5281f Mon Sep 17 00:00:00 2001 From: he <109787524@qq.com> Date: Tue, 14 Oct 2025 14:07:06 +0800 Subject: [PATCH 1/8] =?UTF-8?q?=E4=BF=AE=E6=94=B9luganno?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ReadingCalculate/LuganoWithoutPETCalculateService.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/IRaCIS.Core.Application/Service/ReadingCalculate/LuganoWithoutPETCalculateService.cs b/IRaCIS.Core.Application/Service/ReadingCalculate/LuganoWithoutPETCalculateService.cs index 100debf1a..9dec37a77 100644 --- a/IRaCIS.Core.Application/Service/ReadingCalculate/LuganoWithoutPETCalculateService.cs +++ b/IRaCIS.Core.Application/Service/ReadingCalculate/LuganoWithoutPETCalculateService.cs @@ -28,7 +28,6 @@ namespace IRaCIS.Core.Application.Service.ReadingCalculate IGeneralCalculateService _generalCalculateService, IRepository _readingTaskQuestionAnswerRepository, IMapper _mapper, IUserInfo _userInfo, IStringLocalizer _localizer) : BaseService, ICriterionCalculateService, ILuganoCalculateService { - /// /// 阅片导入 /// @@ -352,7 +351,8 @@ namespace IRaCIS.Core.Application.Service.ReadingCalculate } - }; + } + ; } #endregion From ab91d360b151a53fb6e95435c027e7b5ad7c6040 Mon Sep 17 00:00:00 2001 From: he <109787524@qq.com> Date: Tue, 14 Oct 2025 14:20:23 +0800 Subject: [PATCH 2/8] =?UTF-8?q?=E6=9C=8D=E5=8A=A1=E4=BF=AE=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- IRaCIS.Core.Application/IRaCIS.Core.Application.xml | 10 ++++++++++ .../General/ReadingCalculateService.cs | 1 + 2 files changed, 11 insertions(+) diff --git a/IRaCIS.Core.Application/IRaCIS.Core.Application.xml b/IRaCIS.Core.Application/IRaCIS.Core.Application.xml index 5bc700ff6..9017143c9 100644 --- a/IRaCIS.Core.Application/IRaCIS.Core.Application.xml +++ b/IRaCIS.Core.Application/IRaCIS.Core.Application.xml @@ -957,6 +957,16 @@ + + + 一致性分析结果导出 7 8 分别是自身 和组件一致性 + + + + + + + 获取阅片标准可以导出的列表 diff --git a/IRaCIS.Core.Application/Service/ReadingCalculate/General/ReadingCalculateService.cs b/IRaCIS.Core.Application/Service/ReadingCalculate/General/ReadingCalculateService.cs index 61406ff9a..93089a6f5 100644 --- a/IRaCIS.Core.Application/Service/ReadingCalculate/General/ReadingCalculateService.cs +++ b/IRaCIS.Core.Application/Service/ReadingCalculate/General/ReadingCalculateService.cs @@ -36,6 +36,7 @@ namespace IRaCIS.Core.Application.Service.ReadingCalculate {CriterionType.RECIST1Pointt1_MB,typeof(RECIST1Point1_BMCalculateService) }, {CriterionType.IRECIST1Point1,typeof(IRECIST1Point1CalculateService) }, {CriterionType.Lugano2014,typeof(LuganoCalculateService) }, + {CriterionType.Lugano2014WithoutPET,typeof(LuganoWithoutPETCalculateService) }, {CriterionType.IVUS,typeof(IVUSCalculateService) }, {CriterionType.OCT,typeof(OCTCalculateService) }, {CriterionType.MRIPDFF,typeof(MRIPDFFCalculateService) }, From 6a99e3104a6d88c1817357447cbca085ef022dbc Mon Sep 17 00:00:00 2001 From: he <109787524@qq.com> Date: Tue, 14 Oct 2025 14:28:06 +0800 Subject: [PATCH 3/8] =?UTF-8?q?=E9=AA=8C=E8=AF=81=E4=BF=AE=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Reading/ReadingCriterion/ReadingQuestionService.cs | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/IRaCIS.Core.Application/Service/Reading/ReadingCriterion/ReadingQuestionService.cs b/IRaCIS.Core.Application/Service/Reading/ReadingCriterion/ReadingQuestionService.cs index 69ffea91d..e416e4a53 100644 --- a/IRaCIS.Core.Application/Service/Reading/ReadingCriterion/ReadingQuestionService.cs +++ b/IRaCIS.Core.Application/Service/Reading/ReadingCriterion/ReadingQuestionService.cs @@ -847,7 +847,7 @@ namespace IRaCIS.Core.Application.Service /// - /// 新增修改想想项目表格问题 + /// 新增修改项目表格问题 /// /// /// @@ -861,6 +861,13 @@ namespace IRaCIS.Core.Application.Service //---问题编号重复 throw new BusinessValidationFailedException(_localizer["ReadingQuestion_IdDup"]); } + if (indto.IsPreinstall) + { + if (await _readingTableQuestionTrialRepository.AnyAsync(x => x.ReadingQuestionId == indto.ReadingQuestionId && x.Id != indto.Id && x.IsPreinstall)) + { + throw new BusinessValidationFailedException(_localizer["ReadingQuestion_OnlyOnePreinstall"]); + } + } indto.ParentTriggerValue = string.Join(',', indto.ParentTriggerValueList); indto.RelevanceValue = string.Join(',', indto.RelevanceValueList); From 1959045ab288ea4accbcdf65d88ca39c46332429 Mon Sep 17 00:00:00 2001 From: he <109787524@qq.com> Date: Wed, 15 Oct 2025 10:12:46 +0800 Subject: [PATCH 4/8] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E8=AE=A1=E7=AE=97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ReadingImageTaskService.cs | 42 +++++++++++++++++-- .../ILuganoWithoutPETCalculateService.cs | 21 ++++++++++ .../LuganoWithoutPETCalculateService.cs | 2 +- 3 files changed, 61 insertions(+), 4 deletions(-) create mode 100644 IRaCIS.Core.Application/Service/ReadingCalculate/Interface/ILuganoWithoutPETCalculateService.cs diff --git a/IRaCIS.Core.Application/Service/Reading/ReadingImageTask/ReadingImageTaskService.cs b/IRaCIS.Core.Application/Service/Reading/ReadingImageTask/ReadingImageTaskService.cs index c8843e03c..62638a459 100644 --- a/IRaCIS.Core.Application/Service/Reading/ReadingImageTask/ReadingImageTaskService.cs +++ b/IRaCIS.Core.Application/Service/Reading/ReadingImageTask/ReadingImageTaskService.cs @@ -59,6 +59,7 @@ namespace IRaCIS.Core.Application.Service IRepository _organTrialInfoRepository, IRepository _trialDocumentRepository, ILuganoCalculateService _luganoCalculateService, + ILuganoWithoutPETCalculateService _LuganoWithoutPETCalculateService, //IRepository _readingCustomTagRepository, IRepository _readingTaskQuestionMarkRepository, IRepository _readingTrialCriterionDictionaryRepository, @@ -1794,7 +1795,7 @@ namespace IRaCIS.Core.Application.Service switch (taskInfo.TrialReadingCriterion.CriterionType) { case CriterionType.Lugano2014: - + case CriterionType.Lugano2014WithoutPET: List needSetNa = new List() { QuestionMark.LowPPDAddPercent, @@ -1916,6 +1917,7 @@ namespace IRaCIS.Core.Application.Service switch (taskinfo.TrialReadingCriterion.CriterionType) { case CriterionType.Lugano2014: + await _luganoCalculateService.CalculateMergeTargetLesionStatus(new CalculateTargetLesionStatusInDto() { QuestionId = inDto.QuestionId, @@ -1923,6 +1925,14 @@ namespace IRaCIS.Core.Application.Service RowNumber = mergeRow.RowIndex, }); break; + case CriterionType.Lugano2014WithoutPET: + await _LuganoWithoutPETCalculateService.CalculateMergeTargetLesionStatus(new CalculateTargetLesionStatusInDto() + { + QuestionId = inDto.QuestionId, + VisitTaskId = inDto.VisitTaskId, + RowNumber = mergeRow.RowIndex, + }); + break; } } @@ -1949,6 +1959,7 @@ namespace IRaCIS.Core.Application.Service { case CriterionType.Lugano2014: + case CriterionType.Lugano2014WithoutPET: // (无法评估 或者 状态为消失的非靶病灶) 并且不能是无法评估的病灶 query = query.Where(x => (x.MeasureData == string.Empty || @@ -2252,9 +2263,9 @@ namespace IRaCIS.Core.Application.Service break; case CriterionType.Lugano2014: - + case CriterionType.Lugano2014WithoutPET: // 先找到需要删除的 - + foreach (var item in needDeleteMarkQuestionIds) { // 对于要删除的标记不能删除 要与问题解绑 @@ -2586,6 +2597,7 @@ namespace IRaCIS.Core.Application.Service switch (taskinfo.TrialReadingCriterion.CriterionType) { case CriterionType.Lugano2014: + if (deleteRowInfo.RowIndex % 1 != 0) { await _luganoCalculateService.CalculateTargetLesionStatus(new CalculateTargetLesionStatusInDto() @@ -2596,6 +2608,18 @@ namespace IRaCIS.Core.Application.Service }); } break; + case CriterionType.Lugano2014WithoutPET: + + if (deleteRowInfo.RowIndex % 1 != 0) + { + await _LuganoWithoutPETCalculateService.CalculateTargetLesionStatus(new CalculateTargetLesionStatusInDto() + { + QuestionId = inDto.QuestionId, + VisitTaskId = inDto.VisitTaskId, + RowNumber = deleteRowInfo.RowIndex + }); + } + break; } return ResponseOutput.Ok(true); } @@ -2761,6 +2785,7 @@ namespace IRaCIS.Core.Application.Service } break; case CriterionType.Lugano2014: + case CriterionType.Lugano2014WithoutPET: var targetTablequestionList = await _readingTableQuestionTrialRepository.Where(x => x.TrialCriterionId == taskinfo.TrialReadingCriterionId && x.ReadingQuestionTrial.LesionType == LesionType.TargetLesion).ToListAsync(); @@ -3059,6 +3084,17 @@ namespace IRaCIS.Core.Application.Service }); } break; + case CriterionType.Lugano2014WithoutPET: + if (inDto.RowIndex % 1 != 0) + { + await _LuganoWithoutPETCalculateService.CalculateTargetLesionStatus(new CalculateTargetLesionStatusInDto() + { + QuestionId = inDto.QuestionId, + VisitTaskId = inDto.VisitTaskId, + RowNumber = inDto.RowIndex + }); + } + break; } return result; diff --git a/IRaCIS.Core.Application/Service/ReadingCalculate/Interface/ILuganoWithoutPETCalculateService.cs b/IRaCIS.Core.Application/Service/ReadingCalculate/Interface/ILuganoWithoutPETCalculateService.cs new file mode 100644 index 000000000..7587ba034 --- /dev/null +++ b/IRaCIS.Core.Application/Service/ReadingCalculate/Interface/ILuganoWithoutPETCalculateService.cs @@ -0,0 +1,21 @@ +using IRaCIS.Core.Application.ViewModel; + +namespace IRaCIS.Core.Application.Service.ReadingCalculate.Interface +{ + public interface ILuganoWithoutPETCalculateService + { + /// + /// 计算靶病灶状态 + /// + /// + /// + Task CalculateTargetLesionStatus(CalculateTargetLesionStatusInDto inDto); + + /// + /// 计算靶病灶融合后状态 + /// + /// + /// + Task CalculateMergeTargetLesionStatus(CalculateTargetLesionStatusInDto inDto); + } +} diff --git a/IRaCIS.Core.Application/Service/ReadingCalculate/LuganoWithoutPETCalculateService.cs b/IRaCIS.Core.Application/Service/ReadingCalculate/LuganoWithoutPETCalculateService.cs index 9dec37a77..2aa16011c 100644 --- a/IRaCIS.Core.Application/Service/ReadingCalculate/LuganoWithoutPETCalculateService.cs +++ b/IRaCIS.Core.Application/Service/ReadingCalculate/LuganoWithoutPETCalculateService.cs @@ -26,7 +26,7 @@ namespace IRaCIS.Core.Application.Service.ReadingCalculate IRepository _tumorAssessmentRepository, ISubjectVisitService _subjectVisitService, IGeneralCalculateService _generalCalculateService, - IRepository _readingTaskQuestionAnswerRepository, IMapper _mapper, IUserInfo _userInfo, IStringLocalizer _localizer) : BaseService, ICriterionCalculateService, ILuganoCalculateService + IRepository _readingTaskQuestionAnswerRepository, IMapper _mapper, IUserInfo _userInfo, IStringLocalizer _localizer) : BaseService, ICriterionCalculateService, ILuganoWithoutPETCalculateService { /// /// 阅片导入 From 3292b9f97823c302386470295f312c0bb4f51c5e Mon Sep 17 00:00:00 2001 From: he <109787524@qq.com> Date: Wed, 15 Oct 2025 15:56:32 +0800 Subject: [PATCH 5/8] =?UTF-8?q?=E8=AF=B7=E6=B1=82=E9=A2=91=E7=B9=81?= =?UTF-8?q?=E9=AA=8C=E8=AF=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- IRaCIS.Core.API/Progranm.cs | 2 + .../ServiceCollectionSetup.cs | 1 + IRaCIS.Core.API/appsettings.Event_IRC.json | 8 +- IRaCIS.Core.API/appsettings.Prod_IRC.json | 8 +- IRaCIS.Core.API/appsettings.Test_IRC.json | 11 ++ .../appsettings.Test_IRC_PGSQL.json | 7 ++ IRaCIS.Core.API/appsettings.US_Prod_IRC.json | 7 ++ IRaCIS.Core.API/appsettings.US_Test_IRC.json | 7 ++ IRaCIS.Core.API/appsettings.US_Uat_IRC.json | 8 +- IRaCIS.Core.API/appsettings.Uat_IRC.json | 7 ++ IRaCIS.Core.API/appsettings.json | 7 ++ .../RequestDuplicationFilter.cs | 114 ++++++++++++++++++ .../BusinessFilter/_Config/_AppSettings.cs | 48 ++++++++ .../IRaCIS.Core.Application.xml | 80 +++++++++++- 14 files changed, 310 insertions(+), 5 deletions(-) create mode 100644 IRaCIS.Core.Application/BusinessFilter/LegacyController/RequestDuplicationFilter.cs diff --git a/IRaCIS.Core.API/Progranm.cs b/IRaCIS.Core.API/Progranm.cs index ae03f93a3..69be6d74f 100644 --- a/IRaCIS.Core.API/Progranm.cs +++ b/IRaCIS.Core.API/Progranm.cs @@ -1,6 +1,7 @@ using IRaCIS.Core.API; using IRaCIS.Core.API.HostService; using IRaCIS.Core.Application.BusinessFilter; +using IRaCIS.Core.Application.BusinessFilter.LegacyController.Database.Api; using IRaCIS.Core.Application.Filter; using IRaCIS.Core.Application.MassTransit.Consumer; using IRaCIS.Core.Application.Service; @@ -100,6 +101,7 @@ builder.Services.AddControllers(options => options.Filters.Add(); options.Filters.Add(); options.Filters.Add(); + options.Filters.Add(); }) .AddNewtonsoftJsonSetup(builder.Services); // NewtonsoftJson 序列化 处理 diff --git a/IRaCIS.Core.API/_ServiceExtensions/ServiceCollectionSetup.cs b/IRaCIS.Core.API/_ServiceExtensions/ServiceCollectionSetup.cs index 7541ecf25..075a7fd9e 100644 --- a/IRaCIS.Core.API/_ServiceExtensions/ServiceCollectionSetup.cs +++ b/IRaCIS.Core.API/_ServiceExtensions/ServiceCollectionSetup.cs @@ -28,6 +28,7 @@ public static class ServiceCollectionSetup services.AddOptions().Configure(_configuration.GetSection("AliyunOSS")); services.AddOptions().Configure(_configuration.GetSection("ObjectStoreService")); services.AddOptions().Configure(_configuration.GetSection("EncrypteResponseConfig")); + services.AddOptions().Configure(_configuration.GetSection("RequestDuplicationOptions")); services.AddOptions().Configure(_configuration.GetSection("SystemPacsConfig")); services.Configure(_configuration.GetSection("IRaCISBasicConfig")); diff --git a/IRaCIS.Core.API/appsettings.Event_IRC.json b/IRaCIS.Core.API/appsettings.Event_IRC.json index 392b55d49..6ec66b5b2 100644 --- a/IRaCIS.Core.API/appsettings.Event_IRC.json +++ b/IRaCIS.Core.API/appsettings.Event_IRC.json @@ -69,7 +69,13 @@ "CompanyShortName": "Extensive Imaging", "CompanyShortNameCN": "展影医疗", "IsEnv_US": false + }, + "RequestDuplicationOptions": { + "IsEnabled": true, + "DuplicationWindowMs": 500, + "CacheTimeSeconds": 5, + "ExcludedPaths": [ + ] } - } diff --git a/IRaCIS.Core.API/appsettings.Prod_IRC.json b/IRaCIS.Core.API/appsettings.Prod_IRC.json index b0f6caeed..9985c978b 100644 --- a/IRaCIS.Core.API/appsettings.Prod_IRC.json +++ b/IRaCIS.Core.API/appsettings.Prod_IRC.json @@ -78,6 +78,12 @@ "SystemPacsConfig": { "Port": "11113", "IP": "101.132.193.237" + }, + "RequestDuplicationOptions": { + "IsEnabled": true, + "DuplicationWindowMs": 500, + "CacheTimeSeconds": 5, + "ExcludedPaths": [ + ] } - } diff --git a/IRaCIS.Core.API/appsettings.Test_IRC.json b/IRaCIS.Core.API/appsettings.Test_IRC.json index f266ee6b3..a86722863 100644 --- a/IRaCIS.Core.API/appsettings.Test_IRC.json +++ b/IRaCIS.Core.API/appsettings.Test_IRC.json @@ -160,5 +160,16 @@ "Port": "11113", // PACS服务器IP地址 "IP": "106.14.89.110" + }, + // 重复请求配置 + "RequestDuplicationOptions": { + // 是否启用重复请求检测 + "IsEnabled": true, + // 重复请求时间窗口(毫秒) + "DuplicationWindowMs": 500, + // 缓存请求时间(秒) + "CacheTimeSeconds": 5, + "ExcludedPaths": [ + ] } } diff --git a/IRaCIS.Core.API/appsettings.Test_IRC_PGSQL.json b/IRaCIS.Core.API/appsettings.Test_IRC_PGSQL.json index 4d17342dc..02bcd1cb8 100644 --- a/IRaCIS.Core.API/appsettings.Test_IRC_PGSQL.json +++ b/IRaCIS.Core.API/appsettings.Test_IRC_PGSQL.json @@ -91,5 +91,12 @@ "SystemPacsConfig": { "Port": "11113", "IP": "106.14.89.110" + }, + "RequestDuplicationOptions": { + "IsEnabled": true, + "DuplicationWindowMs": 500, + "CacheTimeSeconds": 5, + "ExcludedPaths": [ + ] } } diff --git a/IRaCIS.Core.API/appsettings.US_Prod_IRC.json b/IRaCIS.Core.API/appsettings.US_Prod_IRC.json index 26935cc91..286366cfc 100644 --- a/IRaCIS.Core.API/appsettings.US_Prod_IRC.json +++ b/IRaCIS.Core.API/appsettings.US_Prod_IRC.json @@ -85,6 +85,13 @@ "SystemPacsConfig": { "Port": "104", "IP": "44.210.231.169" + }, + "RequestDuplicationOptions": { + "IsEnabled": true, + "DuplicationWindowMs": 500, + "CacheTimeSeconds": 5, + "ExcludedPaths": [ + ] } } diff --git a/IRaCIS.Core.API/appsettings.US_Test_IRC.json b/IRaCIS.Core.API/appsettings.US_Test_IRC.json index 043191045..df94467fb 100644 --- a/IRaCIS.Core.API/appsettings.US_Test_IRC.json +++ b/IRaCIS.Core.API/appsettings.US_Test_IRC.json @@ -92,6 +92,13 @@ "SystemPacsConfig": { "Port": "104", "IP": "3.226.182.187" + }, + "RequestDuplicationOptions": { + "IsEnabled": true, + "DuplicationWindowMs": 500, + "CacheTimeSeconds": 5, + "ExcludedPaths": [ + ] } } diff --git a/IRaCIS.Core.API/appsettings.US_Uat_IRC.json b/IRaCIS.Core.API/appsettings.US_Uat_IRC.json index e303cc381..29856f89e 100644 --- a/IRaCIS.Core.API/appsettings.US_Uat_IRC.json +++ b/IRaCIS.Core.API/appsettings.US_Uat_IRC.json @@ -92,6 +92,12 @@ "SystemPacsConfig": { "Port": "104", "IP": "3.226.182.187" + }, + "RequestDuplicationOptions": { + "IsEnabled": true, + "DuplicationWindowMs": 500, + "CacheTimeSeconds": 5, + "ExcludedPaths": [ + ] } - } diff --git a/IRaCIS.Core.API/appsettings.Uat_IRC.json b/IRaCIS.Core.API/appsettings.Uat_IRC.json index c617a54d4..05eaba3c2 100644 --- a/IRaCIS.Core.API/appsettings.Uat_IRC.json +++ b/IRaCIS.Core.API/appsettings.Uat_IRC.json @@ -99,6 +99,13 @@ "SystemPacsConfig": { "Port": "11113", "IP": "101.132.253.119" + }, + "RequestDuplicationOptions": { + "IsEnabled": true, + "DuplicationWindowMs": 500, + "CacheTimeSeconds": 5, + "ExcludedPaths": [ + ] } } diff --git a/IRaCIS.Core.API/appsettings.json b/IRaCIS.Core.API/appsettings.json index 4568c3524..66c347795 100644 --- a/IRaCIS.Core.API/appsettings.json +++ b/IRaCIS.Core.API/appsettings.json @@ -74,5 +74,12 @@ "redirect_uri": "https://oauthlogin.net/oauth/githubcallback", "scope": "repo" } + }, + "RequestDuplicationOptions": { + "IsEnabled": true, + "DuplicationWindowMs": 500, + "CacheTimeSeconds": 5, + "ExcludedPaths": [ + ] } } \ No newline at end of file diff --git a/IRaCIS.Core.Application/BusinessFilter/LegacyController/RequestDuplicationFilter.cs b/IRaCIS.Core.Application/BusinessFilter/LegacyController/RequestDuplicationFilter.cs new file mode 100644 index 000000000..5925332c3 --- /dev/null +++ b/IRaCIS.Core.Application/BusinessFilter/LegacyController/RequestDuplicationFilter.cs @@ -0,0 +1,114 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace IRaCIS.Core.Application.BusinessFilter.LegacyController +{ + using Database.Api; + using DocumentFormat.OpenXml.InkML; + using IRaCIS.Core.Application.Service.Common; + using IRaCIS.Core.Infrastructure; + using Microsoft.AspNetCore.Components.Endpoints; + using Microsoft.AspNetCore.Http; + using Microsoft.AspNetCore.Mvc; + using Microsoft.AspNetCore.Mvc.Filters; + using Microsoft.Extensions.DependencyInjection; + using Microsoft.Extensions.Logging; + using Microsoft.Extensions.Options; + using Minio.Helper; + using Newtonsoft.Json; + using System; + using System.Collections.Generic; + using System.Linq; + using System.Security.Cryptography; + using System.Threading.Tasks; + + namespace Database.Api + { + /// + /// 请求拦截 请求前后的操作 + /// + /// logger + /// loggerHelper + public class RequestDuplicationFilter(ILogger logger, IHttpContextAccessor accessor, IUserInfo _userInfo, IStringLocalizer _localizer, IOptionsMonitor RequestDuplicationOptionsMonitor) : ExceptionFilterAttribute, IAsyncActionFilter + { + /// + /// 传入的参数 + /// + public string Intoparam { get; set; } + + /// + /// 这个是正常记录(请求刚进入的时候) + /// + /// context + /// next + /// 返回的对象 + public async Task OnActionExecutionAsync(ActionExecutingContext context, ActionExecutionDelegate next) + { + this.Intoparam = JsonConvert.SerializeObject(context.ActionArguments); + try + { + this.RequestDuplication(); + } + catch (Exception) + { + throw; + } + + + var resultContext = await next(); + } + + + + /// + /// + /// + private void RequestDuplication() + { + var requestPath = accessor?.HttpContext?.Request?.Path.ToString() ?? string.Empty; + + // 验证请求频繁情况 + if (_userInfo.UserRoleId != default(Guid)&& + RequestDuplicationOptionsMonitor.CurrentValue.IsEnabled && + !RequestDuplicationOptionsMonitor.CurrentValue.ExcludePaths.Contains(requestPath)) + { + RequestInfo requestInfo = new RequestInfo + { + UserRoleId = _userInfo.UserRoleId, + RequestPath = requestPath, + ParameterHash = GenerateParameterHash(this.Intoparam), + RequestTime = DateTime.Now + }; + + IRCSystemInfo.RequestRecordList= IRCSystemInfo.RequestRecordList.Where(x => x.RequestTime >= DateTime.Now.AddSeconds(-RequestDuplicationOptionsMonitor.CurrentValue.CacheTimeSeconds)).ToList(); + + + var requestsTimes = IRCSystemInfo.RequestRecordList.Any(x=> + x.RequestTime>= requestInfo.RequestTime.AddMilliseconds(-RequestDuplicationOptionsMonitor.CurrentValue.DuplicationWindowMs)&& + x.RequestKey== requestInfo.RequestKey); + if (requestsTimes) + { + throw new BusinessValidationFailedException(_localizer["RequestDuplicationFilter_RequestDuplication"]); + } + IRCSystemInfo.RequestRecordList.Add(requestInfo); + } + } + + public string GenerateParameterHash(string parameters) + { + if (string.IsNullOrEmpty(parameters)) + return string.Empty; + + using var sha256 = SHA256.Create(); + var hashBytes = sha256.ComputeHash(Encoding.UTF8.GetBytes(parameters)); + return Convert.ToBase64String(hashBytes); + } + + + + } + } +} diff --git a/IRaCIS.Core.Application/BusinessFilter/_Config/_AppSettings.cs b/IRaCIS.Core.Application/BusinessFilter/_Config/_AppSettings.cs index b725834a6..f4bd22935 100644 --- a/IRaCIS.Core.Application/BusinessFilter/_Config/_AppSettings.cs +++ b/IRaCIS.Core.Application/BusinessFilter/_Config/_AppSettings.cs @@ -105,6 +105,54 @@ public class IRCEncreptOption public List ApiPathList { get; set; } } +/// +/// 请求缓存配置 +/// +public class RequestDuplicationOptions +{ + /// + /// 缓存时间(秒),默认5秒 + /// + public int CacheTimeSeconds { get; set; } = 5; + + /// + /// 重复请求检测时间窗口(毫秒),默认500毫秒 + /// + public int DuplicationWindowMs { get; set; } = 500; + + /// + /// 是否启用防重复请求 + /// + public bool IsEnabled { get; set; } = true; + + /// + /// 需要排除的路径(不进行重复检测) + /// + public List ExcludePaths { get; set; } = new List(); +} + +public static class IRCSystemInfo +{ + public static List RequestRecordList { get; set; } = new List(); +} + +public class RequestInfo +{ + public Guid UserRoleId { get; set; } + + public string RequestPath { get; set; } = string.Empty; + + public string ParameterHash { get; set; } = string.Empty; + + public DateTime RequestTime { get; set; } + + + /// + /// 请求的唯一标识 + /// + public string RequestKey => $"{UserRoleId}_{RequestPath}_{ParameterHash}"; +} + public class IRaCISBasicConfigOption { public string DoctorCodePrefix { get; set; } diff --git a/IRaCIS.Core.Application/IRaCIS.Core.Application.xml b/IRaCIS.Core.Application/IRaCIS.Core.Application.xml index 9017143c9..cc3c6c45b 100644 --- a/IRaCIS.Core.Application/IRaCIS.Core.Application.xml +++ b/IRaCIS.Core.Application/IRaCIS.Core.Application.xml @@ -3233,6 +3233,20 @@ + + + 计算靶病灶状态 + + + + + + + 计算靶病灶融合后状态 + + + + 阅片导入 @@ -13057,7 +13071,7 @@ - 新增修改想想项目表格问题 + 新增修改项目表格问题 @@ -13158,7 +13172,7 @@ - + IR影像阅片 @@ -14398,6 +14412,38 @@ 测试加密API 返回的结果 + + + 请求拦截 请求前后的操作 + + logger + loggerHelper + + + + 请求拦截 请求前后的操作 + + logger + loggerHelper + + + + 传入的参数 + + + + + 这个是正常记录(请求刚进入的时候) + + context + next + 返回的对象 + + + + + + minimal api 生效,但是传统控制器,没生效 @@ -18859,6 +18905,36 @@ + + + 请求缓存配置 + + + + + 缓存时间(秒),默认5秒 + + + + + 重复请求检测时间窗口(毫秒),默认500毫秒 + + + + + 是否启用防重复请求 + + + + + 需要排除的路径(不进行重复检测) + + + + + 请求的唯一标识 + + Id(阅片期Id 或者 访视ID) From 6e75e45942f7284706acec76f60c1ff2d53e008e Mon Sep 17 00:00:00 2001 From: he <109787524@qq.com> Date: Wed, 15 Oct 2025 17:23:18 +0800 Subject: [PATCH 6/8] =?UTF-8?q?=E4=BF=AE=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- IRaCIS.Core.API/Progranm.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/IRaCIS.Core.API/Progranm.cs b/IRaCIS.Core.API/Progranm.cs index 69be6d74f..993353891 100644 --- a/IRaCIS.Core.API/Progranm.cs +++ b/IRaCIS.Core.API/Progranm.cs @@ -101,7 +101,7 @@ builder.Services.AddControllers(options => options.Filters.Add(); options.Filters.Add(); options.Filters.Add(); - options.Filters.Add(); + //options.Filters.Add(); }) .AddNewtonsoftJsonSetup(builder.Services); // NewtonsoftJson 序列化 处理 From b4907bfe9bb6521374428b8c8614273dea03428d Mon Sep 17 00:00:00 2001 From: he <109787524@qq.com> Date: Wed, 15 Oct 2025 17:41:43 +0800 Subject: [PATCH 7/8] =?UTF-8?q?=E4=BB=A3=E7=A0=81=E4=BF=AE=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- IRaCIS.Core.API/Progranm.cs | 2 +- .../LegacyController/RequestDuplicationFilter.cs | 4 +++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/IRaCIS.Core.API/Progranm.cs b/IRaCIS.Core.API/Progranm.cs index 993353891..69be6d74f 100644 --- a/IRaCIS.Core.API/Progranm.cs +++ b/IRaCIS.Core.API/Progranm.cs @@ -101,7 +101,7 @@ builder.Services.AddControllers(options => options.Filters.Add(); options.Filters.Add(); options.Filters.Add(); - //options.Filters.Add(); + options.Filters.Add(); }) .AddNewtonsoftJsonSetup(builder.Services); // NewtonsoftJson 序列化 处理 diff --git a/IRaCIS.Core.Application/BusinessFilter/LegacyController/RequestDuplicationFilter.cs b/IRaCIS.Core.Application/BusinessFilter/LegacyController/RequestDuplicationFilter.cs index 5925332c3..5f30d9315 100644 --- a/IRaCIS.Core.Application/BusinessFilter/LegacyController/RequestDuplicationFilter.cs +++ b/IRaCIS.Core.Application/BusinessFilter/LegacyController/RequestDuplicationFilter.cs @@ -10,6 +10,7 @@ namespace IRaCIS.Core.Application.BusinessFilter.LegacyController using DocumentFormat.OpenXml.InkML; using IRaCIS.Core.Application.Service.Common; using IRaCIS.Core.Infrastructure; + using IRaCIS.Core.Infrastructure.Extention; using Microsoft.AspNetCore.Components.Endpoints; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc; @@ -47,7 +48,8 @@ namespace IRaCIS.Core.Application.BusinessFilter.LegacyController /// 返回的对象 public async Task OnActionExecutionAsync(ActionExecutingContext context, ActionExecutionDelegate next) { - this.Intoparam = JsonConvert.SerializeObject(context.ActionArguments); + this.Intoparam = JsonConvert.SerializeObject( + context.ActionArguments.TryGetValue("inQuery", out var v) ? v : null); try { this.RequestDuplication(); From fbeaec2820c11dd46e8d56fda12de14361ca4336 Mon Sep 17 00:00:00 2001 From: he <109787524@qq.com> Date: Thu, 16 Oct 2025 09:23:10 +0800 Subject: [PATCH 8/8] =?UTF-8?q?=E4=BF=AE=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- IRaCIS.Core.API/Progranm.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/IRaCIS.Core.API/Progranm.cs b/IRaCIS.Core.API/Progranm.cs index 69be6d74f..993353891 100644 --- a/IRaCIS.Core.API/Progranm.cs +++ b/IRaCIS.Core.API/Progranm.cs @@ -101,7 +101,7 @@ builder.Services.AddControllers(options => options.Filters.Add(); options.Filters.Add(); options.Filters.Add(); - options.Filters.Add(); + //options.Filters.Add(); }) .AddNewtonsoftJsonSetup(builder.Services); // NewtonsoftJson 序列化 处理