package jnpf.util; import jnpf.base.UserInfo; import jnpf.config.ConfigValueUtil; import jnpf.database.model.TenantVO; import jnpf.database.util.TenantDataSourceUtil; import jnpf.exception.LoginException; import jnpf.util.data.DataSourceContextHolder; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.redis.core.RedisTemplate; import org.springframework.stereotype.Component; import org.springframework.util.Assert; import java.util.Objects; /** * 租户工具类 * * @author yanwenfu * @create 2023-11-08 */ @Component("ftbCustomTenantUtil") @Slf4j public class CustomTenantUtil { @Autowired private ConfigValueUtil configValueUtil; @Autowired private RedisTemplate redisTemplate; @Autowired private AuthUtil authUtil; private static final String SCHEDULETASK_TOKEN = "scheduletask::fill::token::%s::%s"; public void checkOutTenant(String tenantId) { if (configValueUtil.isMultiTenancy()) { // 判断是不是从外面直接请求 if (StringUtil.isNotEmpty(tenantId)) { //切换成租户库 try { TenantDataSourceUtil.switchTenant(tenantId); } catch (LoginException e) { // throw new RuntimeException("切换租户失败"); log.error("切换租户失败, 租户id: {}", tenantId); } } else { UserInfo userInfo = UserProvider.getUser(); Assert.notNull(userInfo.getUserId(), "缺少租户信息"); DataSourceContextHolder.setDatasource(userInfo.getTenantId(), userInfo.getTenantDbConnectionString(), userInfo.isAssignDataSource()); } } } public void checkOutTenant(String tenantId, String userId) { if (configValueUtil.isMultiTenancy()) { // 判断是不是从外面直接请求 if (StringUtil.isNotEmpty(tenantId)) { TenantVO tenantVO; try { tenantVO = TenantDataSourceUtil.getRemoteTenantInfo(tenantId); TenantDataSourceUtil.switchTenant(tenantId, tenantVO); } catch (LoginException e1) { throw new RuntimeException("切换租户失败"); } if (StringUtil.isEmpty(userId)) { log.error("当前切库用户为空"); return; } String tokenKey = String.format(SCHEDULETASK_TOKEN, tenantId, userId); Object tokenObj = redisTemplate.opsForValue().get(tokenKey); String token = Objects.isNull(tokenObj) ? null : (String) tokenObj; UserInfo userInfo = new UserInfo(); userInfo.setUserId(userId); userInfo.setToken(token); userInfo.setTenantDbConnectionString(tenantVO.getDbName()); userInfo.setAssignDataSource(DataSourceContextHolder.isAssignDataSource()); userInfo.setTenantId(tenantId); if (StringUtil.isNotBlank(token) && UserProvider.isValidToken(token)) { UserProvider.setLocalLoginUser(userInfo); return; } try { token = authUtil.loginTempUser(userId, tenantId); } catch (Exception e) { throw new IllegalStateException("生成token失败", e); } // 检查 token 是否为空 if (token == null || token.isEmpty()) { log.error("当前用户为[{}],租户为[{}]", userId, tenantId); throw new IllegalStateException("Token is empty or null"); } redisTemplate.opsForValue().set(tokenKey, token); // 设置请求头中的 Token userInfo.setToken(token); UserProvider.setLocalLoginUser(userInfo); } else { UserInfo userInfo = UserProvider.getUser(); Assert.notNull(userInfo.getUserId(), "缺少租户信息"); DataSourceContextHolder.setDatasource(userInfo.getTenantId(), userInfo.getTenantDbConnectionString(), userInfo.isAssignDataSource()); } } } }