feat(login): 新增网页AI登录场景WEB_AI

- 在LoginSceneEnum中增加WEB_AI枚举,绑定路径webAi-doLogin
- LoginService扩展WEB_AI登录逻辑:缓存登录态、创建w.tenant.{tenantId}队列并绑定webAiHeadersExchange
- 新增webAiHeadersExchange Bean,交换机名web.ai.headers.exchange
- 用户实体与Service增加web_ai字段及checkWebAILoginRole权限校验
- 提供/webAi-doLogin接口,支持网页端AI独立登录与Token管理
This commit is contained in:
2025-12-05 13:57:16 +08:00
parent cd7aba7aaa
commit e2eb5f9ad0
8 changed files with 72 additions and 4 deletions

View File

@@ -51,6 +51,9 @@ public class LoginService {
/** 大哥使用的 HeadersExchange */
private final HeadersExchange bigBrotherHeadersExchange;
/** 网页AI使用的 HeadersExchange */
private final HeadersExchange webAiHeadersExchange;
/** RabbitMQ 管理组件 */
@Resource
private RabbitAdmin rabbitAdmin;
@@ -108,6 +111,20 @@ public class LoginService {
.match();
rabbitAdmin.declareBinding(binding);
}
if (scene.equals(LoginSceneEnum.WEB_AI)) {
redisTemplate.opsForValue().set("webAI_login:" + user.getTenantId() + ":" + user.getId(), true);
String queueName = "w.tenant." + user.getTenantId();
// 若该租户队列尚未创建,则创建队列并绑定到 HeadersExchange
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(webAiHeadersExchange) // 使用webAi专用交换机
.whereAll(headers)
.match();
rabbitAdmin.declareBinding(binding);
}
SystemTenant systemTenant = tenantMapper.selectById(user.getTenantId());
// 封装返回数据
@@ -120,6 +137,7 @@ public class LoginService {
StpUtil.login(user.getId(), scene.getSaMode());
switch (scene) {
case AI_CHAT:
StpUtil.logout(user.getId(), LoginSceneEnum.WEB_AI.getSaMode());
StpUtil.renewTimeout(DateUtils.dateBetween(systemTenant.getAiExpireTime(),DateUtil.date()));
BeanUtil.copyProperties(user, vo);
vo.setTokenName(StpUtil.getTokenName());
@@ -140,6 +158,14 @@ public class LoginService {
vo.setTokenValue(StpUtil.getTokenValue());
vo.setBrotherExpireTime(systemTenant.getBrotherExpireTime());
return vo;
case WEB_AI:
StpUtil.logout(user.getId(), LoginSceneEnum.AI_CHAT.getSaMode());
StpUtil.renewTimeout(DateUtils.dateBetween(systemTenant.getAiExpireTime(),DateUtil.date()));
BeanUtil.copyProperties(user, vo);
vo.setTokenName(StpUtil.getTokenName());
vo.setTokenValue(StpUtil.getTokenValue());
vo.setAiExpireTime(systemTenant.getAiExpireTime());
return vo;
}
return null;
}
@@ -180,6 +206,7 @@ public class LoginService {
case HOST -> usersService.checkCrawlRole(userId);
case BIG_BROTHER -> usersService.checkbigBrotherlRole(userId);
case AI_CHAT -> usersService.checkAiCHatLoginRole(userId);
case WEB_AI -> usersService.checkWebAILoginRole(userId);
};
if (!pass) {
throw new BusinessException(ErrorCode.LOGIN_NOT_ALLOWED);
@@ -194,19 +221,28 @@ public class LoginService {
*/
public Boolean aiChatLogout(SystemUsersDTO usersDTO) {
// 1. 删除 Redis 中该用户的 AI_CHAT 登录标记
Boolean delete = redisTemplate.delete("ai_login:" + usersDTO.getTenantId() + ":" + usersDTO.getUserId());
Boolean ai_login = redisTemplate.delete("ai_login:" + usersDTO.getTenantId() + ":" + usersDTO.getUserId());
Boolean webAi_login = redisTemplate.delete("webAI_login:" + usersDTO.getTenantId() + ":" + usersDTO.getUserId());
// 2. 使当前 Token 失效
String tokenValue = StpUtil.getTokenValue();
StpUtil.logoutByTokenValue(tokenValue);
log.info("删除租户:{} 登录状态:{}", usersDTO.getTenantId(), delete);
log.info("删除租户:{} 登录状态:{}", usersDTO.getTenantId(), ai_login);
log.info("删除租户:{} 登录状态:{}", usersDTO.getTenantId(), webAi_login);
// 3. 若该租户下已无 AI_CHAT 在线用户,则删除队列
if (!redisUtils.hasKeyByPrefix("ai_login:" + usersDTO.getTenantId())) {
boolean b = rabbitAdmin.deleteQueue("q.tenant." + usersDTO.getTenantId());
log.info("删除租户:{} 队列删除状态:{}", usersDTO.getTenantId(), b);
log.info("删除Ai_CHAT租户:{} 队列删除状态:{}", usersDTO.getTenantId(), b);
}
if (!redisUtils.hasKeyByPrefix("webAI_login:" + usersDTO.getTenantId())) {
boolean b = rabbitAdmin.deleteQueue("w.tenant." + usersDTO.getTenantId());
log.info("删除Web_AI租户:{} 队列删除状态:{}", usersDTO.getTenantId(), b);
}
return true;
}

View File

@@ -83,5 +83,12 @@ public class SystemUsersServiceImpl extends ServiceImpl<SystemUsersMapper,System
return systemUsers.getAiChat() == 1;
}
@Override
public boolean checkWebAILoginRole(Long userId) {
SystemUsers systemUsers = baseMapper.selectById(userId);
return systemUsers.getWebAi() == 1;
}
}