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 redisTemplate; private final Set 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 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.hasAiLoginKeys("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; } }