diff --git a/src/main/java/com/yupi/springbootinit/config/RabbitMQConfig.java b/src/main/java/com/yupi/springbootinit/config/RabbitMQConfig.java index 9840dee..4ad6dca 100644 --- a/src/main/java/com/yupi/springbootinit/config/RabbitMQConfig.java +++ b/src/main/java/com/yupi/springbootinit/config/RabbitMQConfig.java @@ -21,6 +21,8 @@ public class RabbitMQConfig { private static final String QUEUE = "HOST_INFO_QUEUE"; public static final String EXCHANGE_NAME = "user.headers.exchange"; + public static final String AI_CHAT_EXCHANGE_NAME = "ai.chat.headers.exchange"; + public static final String BIG_BROTHER_EXCHANGE_NAME = "big.brother.headers.exchange"; //创建队列 //true:表示持久化 @@ -46,6 +48,20 @@ public class RabbitMQConfig { .build(); } + @Bean + public HeadersExchange aiChatHeadersExchange() { + return ExchangeBuilder.headersExchange(AI_CHAT_EXCHANGE_NAME) + .durable(true) + .build(); + } + + @Bean + public HeadersExchange bigBrotherHeadersExchange() { + return ExchangeBuilder.headersExchange(BIG_BROTHER_EXCHANGE_NAME) + .durable(true) + .build(); + } + @Bean public RabbitAdmin rabbitAdmin(ConnectionFactory cf) { return new RabbitAdmin(cf); diff --git a/src/main/java/com/yupi/springbootinit/service/impl/LoginService.java b/src/main/java/com/yupi/springbootinit/service/impl/LoginService.java index eaa94c1..28b84ea 100644 --- a/src/main/java/com/yupi/springbootinit/service/impl/LoginService.java +++ b/src/main/java/com/yupi/springbootinit/service/impl/LoginService.java @@ -3,6 +3,7 @@ package com.yupi.springbootinit.service.impl; import cn.dev33.satoken.stp.StpUtil; import cn.hutool.core.bean.BeanUtil; import cn.hutool.core.date.DateUtil; +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.yupi.springbootinit.common.ErrorCode; import com.yupi.springbootinit.exception.BusinessException; import com.yupi.springbootinit.mapper.SystemTenantMapper; @@ -44,11 +45,11 @@ public class LoginService { @Resource private RedisTemplate redisTemplate; - /** 已创建过 RabbitMQ 队列的租户 ID 集合,防止重复创建 */ - private final Set created = ConcurrentHashMap.newKeySet(); + /** AI聊天使用的 HeadersExchange */ + private final HeadersExchange aiChatHeadersExchange; - /** 用户事件使用的 HeadersExchange */ - private final HeadersExchange userHeadersExchange; + /** 大哥使用的 HeadersExchange */ + private final HeadersExchange bigBrotherHeadersExchange; /** RabbitMQ 管理组件 */ @Resource @@ -74,26 +75,40 @@ public class LoginService { // 2. 按场景校验角色权限 checkRole(scene, user.getId()); + // 3. AI_CHAT 场景专属逻辑:缓存登录状态并动态创建 RabbitMQ 队列 if (scene.equals(LoginSceneEnum.AI_CHAT)) { // 记录该用户已登录 AI_CHAT redisTemplate.opsForValue().set("ai_login:" + user.getTenantId() + ":" + user.getId(), true); - String queueName = "q.tenant." + user.getTenantId(); // 若该租户队列尚未创建,则创建队列并绑定到 HeadersExchange - if (created.add(String.valueOf(user.getTenantId()))) { Queue queue = QueueBuilder.durable(queueName).build(); rabbitAdmin.declareQueue(queue); - Map headers = Map.of("tenantId", user.getTenantId(), "x-match", "all"); Binding binding = BindingBuilder .bind(queue) - .to(userHeadersExchange) + .to(aiChatHeadersExchange) // 使用AI聊天专用交换机 .whereAll(headers) .match(); rabbitAdmin.declareBinding(binding); - } } + // 3. 大哥场景专属逻辑:缓存登录状态并动态创建 RabbitMQ 队列 + if (scene.equals(LoginSceneEnum.BIG_BROTHER)) { + // 记录该用户已登录 BIG_BROTHER + redisTemplate.opsForValue().set("bigbrother_login:" + user.getTenantId() + ":" + user.getId(), true); + String queueName = "b.tenant." + user.getTenantId(); + // 若该租户队列尚未创建,则创建队列并绑定到 HeadersExchange + Queue queue = QueueBuilder.durable(queueName).build(); + rabbitAdmin.declareQueue(queue); + Map headers = Map.of("tenantId", user.getTenantId(), "x-match", "all"); + Binding binding = BindingBuilder + .bind(queue) + .to(bigBrotherHeadersExchange) // 使用大哥专用交换机 + .whereAll(headers) + .match(); + rabbitAdmin.declareBinding(binding); + } + SystemTenant systemTenant = tenantMapper.selectById(user.getTenantId()); // 封装返回数据 SystemUsersVO vo = new SystemUsersVO(); @@ -189,7 +204,6 @@ public class LoginService { // 3. 若该租户下已无 AI_CHAT 在线用户,则删除队列 if (!redisUtils.hasKeyByPrefix("ai_login:" + usersDTO.getTenantId())) { - created.remove(String.valueOf(usersDTO.getTenantId())); boolean b = rabbitAdmin.deleteQueue("q.tenant." + usersDTO.getTenantId()); log.info("删除租户:{} 队列删除状态:{}", usersDTO.getTenantId(), b); } diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml index aa5c6fa..fd6e876 100644 --- a/src/main/resources/application.yml +++ b/src/main/resources/application.yml @@ -93,9 +93,7 @@ sa-token: # token 名称(同时也是 cookie 名称) token-name: vvtoken # token 有效期(单位:秒) 默认30天,-1 代表永久有效 - timeout: 604800 - # token 最低活跃频率(单位:秒),如果 token 超过此时间没有访问系统就会被冻结,默认-1 代表不限制,永不冻结 - active-timeout: -1 + timeout: 172800 # 是否允许同一账号多地同时登录 (为 true 时允许一起登录, 为 false 时新登录挤掉旧登录) is-concurrent: false # 在多人登录同一账号时,是否共用一个 token (为 true 时所有登录共用一个 token, 为 false 时每次登录新建一个 token)