diff --git a/jeecg-boot/jeecg-boot-base-core/src/main/java/org/jeecg/config/AiChatConfig.java b/jeecg-boot/jeecg-boot-base-core/src/main/java/org/jeecg/config/AiChatConfig.java index cb819d910..c0622b66d 100644 --- a/jeecg-boot/jeecg-boot-base-core/src/main/java/org/jeecg/config/AiChatConfig.java +++ b/jeecg-boot/jeecg-boot-base-core/src/main/java/org/jeecg/config/AiChatConfig.java @@ -49,6 +49,29 @@ public class AiChatConfig { */ private ModelConfig aiModelEmbed = new ModelConfig(); + /** + * AI 聊天助手访问限流配置 + */ + private RateLimitConfig rateLimit = new RateLimitConfig(); + + /** + * AI 聊天助手访问限流参数 + * + * @author scott + * @since 2026-09-01 issues/9871 AI聊天助手访问限流配置优化 + */ + @Data + public static class RateLimitConfig { + /** 每会话每分钟最多发送消息次数,为空或小于等于 0 时不限制 */ + private Integer sendPerSessionPerMinute; + + /** 每 IP 每分钟最多发送消息次数,为空或小于等于 0 时不限制 */ + private Integer sendPerIpPerMinute; + + /** 每会话每小时最多上传文件次数,为空或小于等于 0 时不限制 */ + private Integer uploadPerSessionPerHour; + } + @Data public static class ModelConfig { /** @@ -102,4 +125,4 @@ public class AiChatConfig { private double volume = 0.0; } -} \ No newline at end of file +} diff --git a/jeecg-boot/jeecg-boot-module/jeecg-boot-module-airag/src/main/java/org/jeecg/modules/airag/app/service/impl/AiragChatRateLimitService.java b/jeecg-boot/jeecg-boot-module/jeecg-boot-module-airag/src/main/java/org/jeecg/modules/airag/app/service/impl/AiragChatRateLimitService.java index 968728d2a..ebb2b72e2 100644 --- a/jeecg-boot/jeecg-boot-module/jeecg-boot-module-airag/src/main/java/org/jeecg/modules/airag/app/service/impl/AiragChatRateLimitService.java +++ b/jeecg-boot/jeecg-boot-module/jeecg-boot-module-airag/src/main/java/org/jeecg/modules/airag/app/service/impl/AiragChatRateLimitService.java @@ -3,8 +3,7 @@ package org.jeecg.modules.airag.app.service.impl; import jakarta.servlet.http.HttpServletRequest; import org.jeecg.common.exception.JeecgBootException; import org.jeecg.common.util.IpUtils; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.beans.factory.annotation.Value; +import org.jeecg.config.AiChatConfig; import org.springframework.data.redis.core.RedisTemplate; import org.springframework.stereotype.Service; @@ -22,30 +21,25 @@ import java.util.concurrent.TimeUnit; @Service public class AiragChatRateLimitService { - @Autowired - private RedisTemplate redisTemplate; - - /** - * 每会话每分钟最多发送消息次数 - */ - @Value("${jeecg.airag.rate-limit.send-per-session-per-minute:20}") - private int sendPerSessionPerMinute; - - /** - * 每 IP 每分钟最多发送消息次数 - */ - @Value("${jeecg.airag.rate-limit.send-per-ip-per-minute:60}") - private int sendPerIpPerMinute; - - /** - * 每会话每小时最多上传文件次数 - */ - @Value("${jeecg.airag.rate-limit.upload-per-session-per-hour:20}") - private int uploadPerSessionPerHour; + private final RedisTemplate redisTemplate; + private final AiChatConfig.RateLimitConfig rateLimit; private static final DateTimeFormatter MINUTE_FORMAT = DateTimeFormatter.ofPattern("yyyyMMddHHmm"); private static final DateTimeFormatter HOUR_FORMAT = DateTimeFormatter.ofPattern("yyyyMMddHH"); + /** + * 构造 AI 聊天助手访问限流服务 + * + * @param redisTemplate Redis 操作模板 + * @param aiChatConfig AI 聊天配置 + * @author scott + * @since 2026-09-01 issues/9871 AI聊天助手访问限流配置优化 + */ + public AiragChatRateLimitService(RedisTemplate redisTemplate, AiChatConfig aiChatConfig) { + this.redisTemplate = redisTemplate; + this.rateLimit = aiChatConfig.getRateLimit(); + } + /** * 校验 /airag/chat/send 调用频次 * @@ -56,9 +50,9 @@ public class AiragChatRateLimitService { String clientIp = IpUtils.getIpAddr(request); String minute = LocalDateTime.now().format(MINUTE_FORMAT); - checkLimit("airag:rate:send:session:" + sessionId + ":" + minute, sendPerSessionPerMinute, 120, + checkLimit("airag:rate:send:session:" + sessionId + ":" + minute, rateLimit.getSendPerSessionPerMinute(), 120, "发送消息过于频繁,请稍后再试"); - checkLimit("airag:rate:send:ip:" + clientIp + ":" + minute, sendPerIpPerMinute, 120, + checkLimit("airag:rate:send:ip:" + clientIp + ":" + minute, rateLimit.getSendPerIpPerMinute(), 120, "发送消息过于频繁,请稍后再试"); } @@ -72,9 +66,9 @@ public class AiragChatRateLimitService { String clientIp = IpUtils.getIpAddr(request); String hour = LocalDateTime.now().format(HOUR_FORMAT); - checkLimit("airag:rate:upload:session:" + sessionId + ":" + hour, uploadPerSessionPerHour, 7200, + checkLimit("airag:rate:upload:session:" + sessionId + ":" + hour, rateLimit.getUploadPerSessionPerHour(), 7200, "上传文件过于频繁,请稍后再试"); - checkLimit("airag:rate:upload:ip:" + clientIp + ":" + hour, uploadPerSessionPerHour, 7200, + checkLimit("airag:rate:upload:ip:" + clientIp + ":" + hour, rateLimit.getUploadPerSessionPerHour(), 7200, "上传文件过于频繁,请稍后再试"); } @@ -85,7 +79,10 @@ public class AiragChatRateLimitService { * @param limit 窗口上限 * @param expireSeconds key 过期时间(秒) */ - private void checkLimit(String key, int limit, int expireSeconds, String errorMessage) { + private void checkLimit(String key, Integer limit, int expireSeconds, String errorMessage) { + if (limit == null || limit <= 0) { + return; + } Long count = redisTemplate.opsForValue().increment(key, 1); if (count == null) { return; diff --git a/jeecg-boot/jeecg-module-system/jeecg-system-start/src/main/resources/application-dev.yml b/jeecg-boot/jeecg-module-system/jeecg-system-start/src/main/resources/application-dev.yml index bbc1dec5b..33632a8e8 100644 --- a/jeecg-boot/jeecg-module-system/jeecg-system-start/src/main/resources/application-dev.yml +++ b/jeecg-boot/jeecg-module-system/jeecg-system-start/src/main/resources/application-dev.yml @@ -190,6 +190,14 @@ jeecg: timeout: 60 skills-dir: skills-shell-dir: + # AI聊天助手访问限流配置 + rate-limit: + # 单 session 每分钟上限 + send-per-session-per-minute: 10 + # 单 IP 每分钟上限 + send-per-ip-per-minute: 20 + # 单 session 每小时上限 + upload-per-session-per-hour: 20 # AI文生图绘画 ai-model-draw: # 提供商 OPENAI/ZHIPU/QWEN @@ -254,15 +262,6 @@ jeecg: # Unipush配置 云函数调用 URL 化地址 unicloud: pushUrl: - airag: - # AI聊天助手访问限流配置 - rate-limit: - # 单 session 每分钟上限 - send-per-session-per-minute: 10 - # 单 IP 每分钟上限 - send-per-ip-per-minute: 20 - # 单 session 每小时上限 - upload-per-session-per-hour: 20 # 平台上线安全配置 firewall: # 数据源安全 (开启后,Online报表和图表的数据源为必填) diff --git a/jeecg-boot/jeecg-module-system/jeecg-system-start/src/main/resources/application-dm8.yml b/jeecg-boot/jeecg-module-system/jeecg-system-start/src/main/resources/application-dm8.yml index cea7d06ed..034655775 100644 --- a/jeecg-boot/jeecg-module-system/jeecg-system-start/src/main/resources/application-dm8.yml +++ b/jeecg-boot/jeecg-module-system/jeecg-system-start/src/main/resources/application-dm8.yml @@ -166,6 +166,14 @@ jeecg: timeout: 60 skills-dir: skills-shell-dir: + # AI聊天助手访问限流配置 + rate-limit: + # 单 session 每分钟上限 + send-per-session-per-minute: 10 + # 单 IP 每分钟上限 + send-per-ip-per-minute: 20 + # 单 session 每小时上限 + upload-per-session-per-hour: 20 # AI文生图绘画 ai-model-draw: # 提供商 OPENAI/ZHIPU/QWEN @@ -225,15 +233,6 @@ jeecg: endpoint: https://api.search.brave.com/res/v1/web/search count: 10 timeout: 15 - airag: - # AI聊天助手访问限流配置 - rate-limit: - # 单 session 每分钟上限 - send-per-session-per-minute: 10 - # 单 IP 每分钟上限 - send-per-ip-per-minute: 20 - # 单 session 每小时上限 - upload-per-session-per-hour: 20 # 平台上线安全配置 firewall: # 数据源安全 (开启后,Online报表和图表的数据源为必填) diff --git a/jeecg-boot/jeecg-module-system/jeecg-system-start/src/main/resources/application-docker.yml b/jeecg-boot/jeecg-module-system/jeecg-system-start/src/main/resources/application-docker.yml index f9e2451e6..762ec122f 100644 --- a/jeecg-boot/jeecg-module-system/jeecg-system-start/src/main/resources/application-docker.yml +++ b/jeecg-boot/jeecg-module-system/jeecg-system-start/src/main/resources/application-docker.yml @@ -188,6 +188,14 @@ jeecg: timeout: 60 skills-dir: skills-shell-dir: + # AI聊天助手访问限流配置 + rate-limit: + # 单 session 每分钟上限 + send-per-session-per-minute: 10 + # 单 IP 每分钟上限 + send-per-ip-per-minute: 20 + # 单 session 每小时上限 + upload-per-session-per-hour: 20 # AI文生图绘画 ai-model-draw: # 提供商 OPENAI/ZHIPU/QWEN @@ -377,4 +385,4 @@ justauth: cache: type: default prefix: 'demo::' - timeout: 1h \ No newline at end of file + timeout: 1h diff --git a/jeecg-boot/jeecg-module-system/jeecg-system-start/src/main/resources/application-kingbase8.yml b/jeecg-boot/jeecg-module-system/jeecg-system-start/src/main/resources/application-kingbase8.yml index daaf43b57..52d562409 100644 --- a/jeecg-boot/jeecg-module-system/jeecg-system-start/src/main/resources/application-kingbase8.yml +++ b/jeecg-boot/jeecg-module-system/jeecg-system-start/src/main/resources/application-kingbase8.yml @@ -183,6 +183,14 @@ jeecg: timeout: 60 skills-dir: skills-shell-dir: + # AI聊天助手访问限流配置 + rate-limit: + # 单 session 每分钟上限 + send-per-session-per-minute: 10 + # 单 IP 每分钟上限 + send-per-ip-per-minute: 20 + # 单 session 每小时上限 + upload-per-session-per-hour: 20 # AI文生图绘画 ai-model-draw: # 提供商 OPENAI/ZHIPU/QWEN @@ -245,15 +253,6 @@ jeecg: # Unipush配置 云函数调用 URL 化地址 unicloud: pushUrl: - airag: - # AI聊天助手访问限流配置 - rate-limit: - # 单 session 每分钟上限 - send-per-session-per-minute: 10 - # 单 IP 每分钟上限 - send-per-ip-per-minute: 20 - # 单 session 每小时上限 - upload-per-session-per-hour: 20 # 平台上线安全配置 firewall: # 数据源安全 (开启后,Online报表和图表的数据源为必填) diff --git a/jeecg-boot/jeecg-module-system/jeecg-system-start/src/main/resources/application-oracle.yml b/jeecg-boot/jeecg-module-system/jeecg-system-start/src/main/resources/application-oracle.yml index 85fb2c7f1..b2e06bef1 100644 --- a/jeecg-boot/jeecg-module-system/jeecg-system-start/src/main/resources/application-oracle.yml +++ b/jeecg-boot/jeecg-module-system/jeecg-system-start/src/main/resources/application-oracle.yml @@ -180,6 +180,14 @@ jeecg: timeout: 60 skills-dir: skills-shell-dir: + # AI聊天助手访问限流配置 + rate-limit: + # 单 session 每分钟上限 + send-per-session-per-minute: 10 + # 单 IP 每分钟上限 + send-per-ip-per-minute: 20 + # 单 session 每小时上限 + upload-per-session-per-hour: 20 # AI文生图绘画 ai-model-draw: # 提供商 OPENAI/ZHIPU/QWEN @@ -239,15 +247,6 @@ jeecg: endpoint: https://api.search.brave.com/res/v1/web/search count: 10 timeout: 15 - airag: - # AI聊天助手访问限流配置 - rate-limit: - # 单 session 每分钟上限 - send-per-session-per-minute: 10 - # 单 IP 每分钟上限 - send-per-ip-per-minute: 20 - # 单 session 每小时上限 - upload-per-session-per-hour: 20 # 平台上线安全配置 firewall: # 数据源安全 (开启后,Online报表和图表的数据源为必填) diff --git a/jeecg-boot/jeecg-module-system/jeecg-system-start/src/main/resources/application-postgresql.yml b/jeecg-boot/jeecg-module-system/jeecg-system-start/src/main/resources/application-postgresql.yml index ebe2a2460..154c11e78 100644 --- a/jeecg-boot/jeecg-module-system/jeecg-system-start/src/main/resources/application-postgresql.yml +++ b/jeecg-boot/jeecg-module-system/jeecg-system-start/src/main/resources/application-postgresql.yml @@ -193,6 +193,14 @@ jeecg: timeout: 60 skills-dir: skills-shell-dir: + # AI聊天助手访问限流配置 + rate-limit: + # 单 session 每分钟上限 + send-per-session-per-minute: 10 + # 单 IP 每分钟上限 + send-per-ip-per-minute: 20 + # 单 session 每小时上限 + upload-per-session-per-hour: 20 # AI文生图绘画 ai-model-draw: # 提供商 OPENAI/ZHIPU/QWEN @@ -252,15 +260,6 @@ jeecg: endpoint: https://api.search.brave.com/res/v1/web/search count: 10 timeout: 15 - airag: - # AI聊天助手访问限流配置 - rate-limit: - # 单 session 每分钟上限 - send-per-session-per-minute: 10 - # 单 IP 每分钟上限 - send-per-ip-per-minute: 20 - # 单 session 每小时上限 - upload-per-session-per-hour: 20 # 平台上线安全配置 firewall: # 数据源安全 (开启后,Online报表和图表的数据源为必填) diff --git a/jeecg-boot/jeecg-module-system/jeecg-system-start/src/main/resources/application-prod.yml b/jeecg-boot/jeecg-module-system/jeecg-system-start/src/main/resources/application-prod.yml index 1b28ace3d..9665a119a 100644 --- a/jeecg-boot/jeecg-module-system/jeecg-system-start/src/main/resources/application-prod.yml +++ b/jeecg-boot/jeecg-module-system/jeecg-system-start/src/main/resources/application-prod.yml @@ -186,6 +186,14 @@ jeecg: timeout: 60 skills-dir: skills-shell-dir: + # AI聊天助手访问限流配置 + rate-limit: + # 单 session 每分钟上限 + send-per-session-per-minute: 10 + # 单 IP 每分钟上限 + send-per-ip-per-minute: 20 + # 单 session 每小时上限 + upload-per-session-per-hour: 20 # AI文生图绘画 ai-model-draw: # 提供商 OPENAI/ZHIPU/QWEN diff --git a/jeecg-boot/jeecg-module-system/jeecg-system-start/src/main/resources/application-sqlserver.yml b/jeecg-boot/jeecg-module-system/jeecg-system-start/src/main/resources/application-sqlserver.yml index ae97b616c..d9ff4720b 100644 --- a/jeecg-boot/jeecg-module-system/jeecg-system-start/src/main/resources/application-sqlserver.yml +++ b/jeecg-boot/jeecg-module-system/jeecg-system-start/src/main/resources/application-sqlserver.yml @@ -175,6 +175,14 @@ jeecg: timeout: 60 skills-dir: skills-shell-dir: + # AI聊天助手访问限流配置 + rate-limit: + # 单 session 每分钟上限 + send-per-session-per-minute: 10 + # 单 IP 每分钟上限 + send-per-ip-per-minute: 20 + # 单 session 每小时上限 + upload-per-session-per-hour: 20 # AI文生图绘画 ai-model-draw: # 提供商 OPENAI/ZHIPU/QWEN @@ -234,15 +242,6 @@ jeecg: endpoint: https://api.search.brave.com/res/v1/web/search count: 10 timeout: 15 - airag: - # AI聊天助手访问限流配置 - rate-limit: - # 单 session 每分钟上限 - send-per-session-per-minute: 10 - # 单 IP 每分钟上限 - send-per-ip-per-minute: 20 - # 单 session 每小时上限 - upload-per-session-per-hour: 20 # 平台上线安全配置 firewall: # 数据源安全 (开启后,Online报表和图表的数据源为必填) diff --git a/jeecg-boot/jeecg-module-system/jeecg-system-start/src/main/resources/application-test.yml b/jeecg-boot/jeecg-module-system/jeecg-system-start/src/main/resources/application-test.yml index ada1c1af8..e872f38ae 100644 --- a/jeecg-boot/jeecg-module-system/jeecg-system-start/src/main/resources/application-test.yml +++ b/jeecg-boot/jeecg-module-system/jeecg-system-start/src/main/resources/application-test.yml @@ -190,6 +190,14 @@ jeecg: timeout: 60 skills-dir: skills-shell-dir: + # AI聊天助手访问限流配置 + rate-limit: + # 单 session 每分钟上限 + send-per-session-per-minute: 10 + # 单 IP 每分钟上限 + send-per-ip-per-minute: 20 + # 单 session 每小时上限 + upload-per-session-per-hour: 20 # AI文生图绘画 ai-model-draw: # 提供商 OPENAI/ZHIPU/QWEN