1.添加 rabbitmq
2.在 AI 登录时 创建消息队列
This commit is contained in:
4
pom.xml
4
pom.xml
@@ -126,6 +126,10 @@
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-amqp</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.dromara.x-file-storage</groupId>
|
||||
<artifactId>x-file-storage-spring</artifactId>
|
||||
|
||||
@@ -0,0 +1,64 @@
|
||||
package com.yupi.springbootinit.config;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonAutoDetect;
|
||||
import com.fasterxml.jackson.annotation.PropertyAccessor;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.fasterxml.jackson.databind.SerializationFeature;
|
||||
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
|
||||
import org.springframework.amqp.core.ExchangeBuilder;
|
||||
import org.springframework.amqp.core.HeadersExchange;
|
||||
import org.springframework.amqp.core.Queue;
|
||||
import org.springframework.amqp.rabbit.connection.ConnectionFactory;
|
||||
import org.springframework.amqp.rabbit.core.RabbitAdmin;
|
||||
import org.springframework.amqp.support.converter.Jackson2JsonMessageConverter;
|
||||
import org.springframework.amqp.support.converter.MessageConverter;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
@Configuration
|
||||
public class RabbitMQConfig {
|
||||
|
||||
private static final String QUEUE = "HOST_INFO_QUEUE";
|
||||
|
||||
public static final String EXCHANGE_NAME = "user.headers.exchange";
|
||||
|
||||
//创建队列
|
||||
//true:表示持久化
|
||||
//队列在默认情况下放到内存,rabbitmq重启后就丢失了,如果希望重启后,队列
|
||||
//数据还能使用,就需要持久化
|
||||
@Bean
|
||||
public Queue hostInfoQueue(){
|
||||
return new Queue(QUEUE,true);
|
||||
}
|
||||
|
||||
//
|
||||
// @Bean
|
||||
// public MessageConverter messageConverter(){
|
||||
// return new Jackson2JsonMessageConverter();
|
||||
// }
|
||||
|
||||
|
||||
|
||||
@Bean
|
||||
public HeadersExchange userHeadersExchange() {
|
||||
return ExchangeBuilder.headersExchange(EXCHANGE_NAME)
|
||||
.durable(true)
|
||||
.build();
|
||||
}
|
||||
|
||||
@Bean
|
||||
public RabbitAdmin rabbitAdmin(ConnectionFactory cf) {
|
||||
return new RabbitAdmin(cf);
|
||||
}
|
||||
|
||||
|
||||
@Bean
|
||||
public MessageConverter messageConverter() {
|
||||
ObjectMapper om = new ObjectMapper();
|
||||
om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
|
||||
om.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);
|
||||
om.registerModule(new JavaTimeModule());
|
||||
return new Jackson2JsonMessageConverter(om);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,37 +1,49 @@
|
||||
package com.yupi.springbootinit.config;
|
||||
|
||||
|
||||
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.data.redis.connection.RedisConnectionFactory;
|
||||
import org.springframework.data.redis.core.RedisTemplate;
|
||||
import org.springframework.data.redis.serializer.RedisSerializer;
|
||||
import org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer;
|
||||
import org.springframework.data.redis.serializer.StringRedisSerializer;
|
||||
|
||||
@Configuration
|
||||
public class RedisConfig {
|
||||
|
||||
|
||||
@Bean(name="redisTemplate")
|
||||
public RedisTemplate<String, String> redisTemplate(RedisConnectionFactory factory) {
|
||||
RedisTemplate<String, String> template = new RedisTemplate<>();
|
||||
RedisSerializer<String> redisSerializer = new StringRedisSerializer();
|
||||
// @Bean(name="redisTemplate")
|
||||
// public RedisTemplate<String, String> redisTemplate(RedisConnectionFactory factory) {
|
||||
// RedisTemplate<String, String> template = new RedisTemplate<>();
|
||||
// RedisSerializer<String> redisSerializer = new StringRedisSerializer();
|
||||
// template.setConnectionFactory(factory);
|
||||
// //key序列化方式
|
||||
// template.setKeySerializer(redisSerializer);
|
||||
// //value序列化
|
||||
// template.setValueSerializer(redisSerializer);
|
||||
// //value hashmap序列化
|
||||
// template.setHashValueSerializer(redisSerializer);
|
||||
// //key haspmap序列化
|
||||
// template.setHashKeySerializer(redisSerializer);
|
||||
// //
|
||||
// return template;
|
||||
// }
|
||||
@Bean
|
||||
public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory factory) {
|
||||
RedisTemplate<String, Object> template = new RedisTemplate<>();
|
||||
template.setConnectionFactory(factory);
|
||||
//key序列化方式
|
||||
template.setKeySerializer(redisSerializer);
|
||||
//value序列化
|
||||
template.setValueSerializer(redisSerializer);
|
||||
//value hashmap序列化
|
||||
template.setHashValueSerializer(redisSerializer);
|
||||
//key haspmap序列化
|
||||
template.setHashKeySerializer(redisSerializer);
|
||||
//
|
||||
|
||||
// 使用 JSON 序列化器
|
||||
GenericJackson2JsonRedisSerializer jsonSerializer = new GenericJackson2JsonRedisSerializer();
|
||||
|
||||
template.setKeySerializer(new StringRedisSerializer());
|
||||
template.setValueSerializer(jsonSerializer);
|
||||
template.setHashKeySerializer(new StringRedisSerializer());
|
||||
template.setHashValueSerializer(jsonSerializer);
|
||||
|
||||
template.afterPropertiesSet();
|
||||
return template;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -47,7 +47,8 @@ public class SaTokenConfigure implements WebMvcConfigurer {
|
||||
"/tenant/get-id-by-name",
|
||||
"/user/bigbrother-doLogin",
|
||||
"/user/aiChat-doLogin",
|
||||
"/error"
|
||||
"/user/aiChat-logout",
|
||||
"/error",
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -57,6 +57,10 @@ public class UserController {
|
||||
// return ResultUtils.success(systemUsersVO);
|
||||
}
|
||||
|
||||
@PostMapping("aiChat-logout")
|
||||
public BaseResponse<Boolean> aiChatLogout(@RequestBody SystemUsersDTO usersDTO){
|
||||
return ResultUtils.success(loginService.aiChatLogout(usersDTO));
|
||||
}
|
||||
|
||||
//
|
||||
// private SystemUsers getUserByName(@RequestBody SystemUsersDTO usersDTO) {
|
||||
|
||||
@@ -29,4 +29,6 @@ public class SystemUsersDTO {
|
||||
* 租户编号
|
||||
*/
|
||||
private Long tenantId;
|
||||
|
||||
private Long userId;
|
||||
}
|
||||
@@ -11,17 +11,51 @@ import com.yupi.springbootinit.model.enums.LoginSceneEnum;
|
||||
import com.yupi.springbootinit.model.vo.user.SystemUsersVO;
|
||||
import com.yupi.springbootinit.service.SystemUsersService;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.amqp.core.*;
|
||||
import org.springframework.amqp.rabbit.core.RabbitAdmin;
|
||||
import org.springframework.data.redis.core.RedisTemplate;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
@Slf4j
|
||||
@Service
|
||||
@RequiredArgsConstructor
|
||||
public class LoginService {
|
||||
|
||||
private final SystemUsersService usersService;
|
||||
|
||||
@Resource
|
||||
private RedisTemplate<String,Boolean> redisTemplate;
|
||||
|
||||
private final Set<String> created = ConcurrentHashMap.newKeySet();
|
||||
private final HeadersExchange userHeadersExchange;
|
||||
@Resource
|
||||
private RabbitAdmin rabbitAdmin;
|
||||
|
||||
public SystemUsersVO login(LoginSceneEnum scene, SystemUsersDTO dto) {
|
||||
SystemUsers user = validateUser(dto); // 校验用户名、密码、状态、租户过期
|
||||
checkRole(scene, user.getId()); // 按场景做角色校验
|
||||
if (scene.equals(LoginSceneEnum.AI_CHAT)) {
|
||||
redisTemplate.opsForValue().set("ai_login:"+user.getTenantId() ,true);
|
||||
String queueName = "q.tenant." + user.getTenantId();
|
||||
if (created.add(String.valueOf(user.getTenantId()))) {
|
||||
Queue queue = QueueBuilder.durable(queueName).build();
|
||||
rabbitAdmin.declareQueue(queue);
|
||||
|
||||
Map<String, Object> headers = Map.of("tenantId", user.getTenantId(), "x-match", "all");
|
||||
Binding binding = BindingBuilder
|
||||
.bind(queue)
|
||||
.to(userHeadersExchange) // ← 传 Exchange 对象
|
||||
.whereAll(headers)
|
||||
.match();
|
||||
rabbitAdmin.declareBinding(binding);
|
||||
}
|
||||
}
|
||||
Long second = usersService.getTenantExpiredTime(dto.getTenantId());
|
||||
// Sa-Token 登录
|
||||
StpUtil.login(user.getId(), scene.getSaMode());
|
||||
@@ -53,4 +87,12 @@ public class LoginService {
|
||||
};
|
||||
if (!pass) throw new BusinessException(ErrorCode.LOGIN_NOW_ALLOWED);
|
||||
}
|
||||
|
||||
public Boolean aiChatLogout(SystemUsersDTO usersDTO) {
|
||||
Boolean delete = redisTemplate.delete("ai_login:"+usersDTO.getTenantId());
|
||||
created.remove(String.valueOf(usersDTO.getTenantId()));
|
||||
log.info("删除租户:{}登录状态:{}",usersDTO.getTenantId(),delete);
|
||||
StpUtil.logout(usersDTO.getUserId());
|
||||
return true;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user