Files
tkcrawl-client/src/main/java/com/yupi/springbootinit/service/impl/LoginService.java

106 lines
4.6 KiB
Java

package com.yupi.springbootinit.service.impl;
import cn.dev33.satoken.stp.StpUtil;
import cn.hutool.core.bean.BeanUtil;
import com.yupi.springbootinit.common.ErrorCode;
import com.yupi.springbootinit.exception.BusinessException;
import com.yupi.springbootinit.model.dto.user.SystemUsersDTO;
import com.yupi.springbootinit.model.entity.SystemUsers;
import com.yupi.springbootinit.model.enums.CommonStatusEnum;
import com.yupi.springbootinit.model.enums.LoginSceneEnum;
import com.yupi.springbootinit.model.vo.user.SystemUsersVO;
import com.yupi.springbootinit.service.SystemUsersService;
import com.yupi.springbootinit.utils.RedisUtils;
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;
@Resource
private RedisUtils redisUtils;
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()+":"+user.getId(),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());
StpUtil.renewTimeout(second);
SystemUsersVO vo = new SystemUsersVO();
BeanUtil.copyProperties(user, vo);
vo.setTokenName(StpUtil.getTokenName());
vo.setTokenValue(StpUtil.getTokenValue());
return vo;
}
private SystemUsers validateUser(SystemUsersDTO dto) {
SystemUsers user = usersService.getUserByUserName(dto.getUsername(), dto.getTenantId());
if (user == null) throw new BusinessException(ErrorCode.USERNAME_OR_PASSWORD_ERROR);
if (!usersService.isPasswordMatch(dto.getPassword(), user.getPassword()))
throw new BusinessException(ErrorCode.USERNAME_OR_PASSWORD_ERROR);
if (CommonStatusEnum.isDisable(Integer.valueOf(user.getStatus())))
throw new BusinessException(ErrorCode.USER_DISABLE);
if (usersService.isExpired(dto.getTenantId()))
throw new BusinessException(ErrorCode.PACKAGE_EXPIRED);
return user;
}
private void checkRole(LoginSceneEnum scene, Long userId) {
Boolean pass = switch (scene) {
case HOST -> usersService.checkCrawlRole(userId);
case BIG_BROTHER -> usersService.checkbigBrotherlRole(userId);
case AI_CHAT -> usersService.checkAiCHatLoginRole(userId);
};
if (!pass) throw new BusinessException(ErrorCode.LOGIN_NOW_ALLOWED);
}
public Boolean aiChatLogout(SystemUsersDTO usersDTO) {
Boolean delete = redisTemplate.delete("ai_login:"+usersDTO.getTenantId()+":"+usersDTO.getUserId());
StpUtil.logout(usersDTO.getUserId());
log.info("删除租户:{}登录状态:{}",usersDTO.getTenantId(),delete);
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);
}
return true;
}
}