瀏覽代碼

销售端登录改造

yh 3 周之前
父節點
當前提交
432503bed9

+ 2 - 2
fs-company/src/main/java/com/fs/company/controller/company/CompanyLoginController.java

@@ -76,7 +76,7 @@ public class CompanyLoginController
         AjaxResult ajax = AjaxResult.success();
         // 生成令牌
         String token = loginService.login(loginBody.getUsername(), loginBody.getPassword(), loginBody.getCode(),
-                loginBody.getUuid());
+                loginBody.getUuid(),loginBody.getTenantCode());
         ajax.put(Constants.TOKEN, token);
         return ajax;
     }
@@ -148,7 +148,7 @@ public class CompanyLoginController
     public boolean checkIsNeedCheck(@RequestBody LoginBody loginBody)
     {
 //        return false;
-        return loginService.checkIsNeedCheck(loginBody.getUsername(), loginBody.getPassword(), loginBody.getCode(), loginBody.getUuid());
+        return loginService.checkIsNeedCheck(loginBody.getUsername(), loginBody.getPassword(), loginBody.getCode(), loginBody.getUuid(), loginBody.getTenantCode());
     }
 
     @PostMapping("/getWechatQrCode")

+ 98 - 0
fs-company/src/main/java/com/fs/framework/datasource/TenantDataSourceManager.java

@@ -0,0 +1,98 @@
+package com.fs.framework.datasource;
+
+import com.alibaba.druid.pool.DruidDataSource;
+import com.fs.tenant.domain.TenantInfo;
+import org.springframework.stereotype.Component;
+
+import javax.annotation.Resource;
+import javax.sql.DataSource;
+import java.lang.reflect.Field;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+
+@Component
+public class TenantDataSourceManager {
+
+    @Resource
+    private DynamicDataSource dynamicDataSource;
+
+    /**
+     * 租户数据源缓存
+     */
+    private static final Map<String, DataSource> TENANT_DS_CACHE = new ConcurrentHashMap<>();
+
+    /**
+     * 切换到租户数据源(不存在则创建)
+     */
+    public void switchTenant(TenantInfo tenantInfo) {
+
+        // 用租户主键作为唯一标识
+        String tenantKey = buildTenantKey(tenantInfo.getId());
+
+        if (!TENANT_DS_CACHE.containsKey(tenantKey)) {
+            synchronized (this) {
+                if (!TENANT_DS_CACHE.containsKey(tenantKey)) {
+
+                    DataSource tenantDs = createTenantDataSource(tenantInfo);
+                    TENANT_DS_CACHE.put(tenantKey, tenantDs);
+
+                    // 动态追加到已解析的数据源
+                    Map<Object, DataSource> resolvedMap = getResolvedDataSources();
+                    resolvedMap.put(tenantKey, tenantDs);
+                }
+            }
+        }
+
+        // ThreadLocal 切库
+        DynamicDataSourceContextHolder.setDataSourceType(tenantKey);
+    }
+
+    private String buildTenantKey(Long tenantId) {
+        return "tenant:" + tenantId;
+    }
+
+
+
+    /**
+     * 清理 ThreadLocal
+     */
+    public void clear() {
+        DynamicDataSourceContextHolder.clearDataSourceType();
+    }
+
+    /**
+     * 创建租户数据源(MySQL + Druid)
+     */
+    private DataSource createTenantDataSource(TenantInfo tenant) {
+
+        DruidDataSource ds = new DruidDataSource();
+        ds.setUrl(tenant.getDbUrl());
+        ds.setUsername(tenant.getDbAccount());
+        ds.setPassword(tenant.getDbPwd());
+
+        // 统一 MySQL
+        ds.setDriverClassName("com.mysql.cj.jdbc.Driver");
+
+        ds.setInitialSize(5);
+        ds.setMinIdle(10);
+        ds.setMaxActive(20);
+        ds.setMaxWait(60000);
+
+        return ds;
+    }
+
+    /**
+     * 反射获取 AbstractRoutingDataSource.resolvedDataSources
+     */
+    @SuppressWarnings("unchecked")
+    private Map<Object, DataSource> getResolvedDataSources() {
+        try {
+            Field field = org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource
+                    .class.getDeclaredField("resolvedDataSources");
+            field.setAccessible(true);
+            return (Map<Object, DataSource>) field.get(dynamicDataSource);
+        } catch (Exception e) {
+            throw new IllegalStateException("获取 resolvedDataSources 失败", e);
+        }
+    }
+}

+ 10 - 0
fs-company/src/main/java/com/fs/framework/security/LoginBody.java

@@ -27,6 +27,16 @@ public class LoginBody
      */
     private String uuid = "";
 
+    private String tenantCode;
+
+    public String getTenantCode() {
+        return tenantCode;
+    }
+
+    public void setTenantCode(String tenantCode) {
+        this.tenantCode = tenantCode;
+    }
+
     public String getUsername()
     {
         return username;

+ 11 - 0
fs-company/src/main/java/com/fs/framework/security/LoginUser.java

@@ -67,7 +67,18 @@ public class LoginUser implements UserDetails
 
     private Company company;
 
+    /**
+     * 租户id
+     */
+    private Long tenantId;
 
+    public Long getTenantId() {
+        return tenantId;
+    }
+
+    public void setTenantId(Long tenantId) {
+        this.tenantId = tenantId;
+    }
 
     public static long getSerialVersionUID() {
         return serialVersionUID;

+ 60 - 8
fs-company/src/main/java/com/fs/framework/security/filter/JwtAuthenticationTokenFilter.java

@@ -1,11 +1,19 @@
 package com.fs.framework.security.filter;
 
+import com.alibaba.fastjson.JSONObject;
 import com.fs.common.core.redis.RedisCache;
+import com.fs.common.enums.DataSourceType;
 import com.fs.common.utils.StringUtils;
 
+import com.fs.core.config.TenantConfigContext;
+import com.fs.core.config.WxMpProperties;
+import com.fs.framework.datasource.DynamicDataSource;
+import com.fs.framework.datasource.DynamicDataSourceContextHolder;
 import com.fs.framework.security.LoginUser;
 import com.fs.framework.security.SecurityUtils;
 import com.fs.framework.service.TokenService;
+import com.fs.system.domain.SysConfig;
+import com.fs.system.mapper.SysConfigMapper;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
 import org.springframework.security.core.context.SecurityContextHolder;
@@ -18,6 +26,7 @@ import javax.servlet.ServletException;
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
 import java.io.IOException;
+import java.util.List;
 
 /**
  * token过滤器 验证token有效性
@@ -31,18 +40,61 @@ public class JwtAuthenticationTokenFilter extends OncePerRequestFilter
     private TokenService tokenService;
     @Autowired
     private RedisCache redisCache;
+    @Autowired
+    private DynamicDataSource dynamicDataSource;
+    @Autowired
+    private SysConfigMapper sysConfigMapper;
+    @Autowired
+    private WxMpProperties wxMpProperties;
+
     @Override
     protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain)
             throws ServletException, IOException
     {
-        LoginUser loginUser = tokenService.getLoginUser(request);
-        if (StringUtils.isNotNull(loginUser) && StringUtils.isNull(SecurityUtils.getAuthentication()))
-        {
-            tokenService.verifyToken(loginUser);
-            UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken(loginUser, null, loginUser.getAuthorities());
-            authenticationToken.setDetails(new WebAuthenticationDetailsSource().buildDetails(request));
-            SecurityContextHolder.getContext().setAuthentication(authenticationToken);
+        try {
+            LoginUser loginUser = tokenService.getLoginUser(request);
+            if (StringUtils.isNotNull(loginUser) && StringUtils.isNull(SecurityUtils.getAuthentication()))
+            {
+                // 根据 tenantId 切换数据源
+                Long tenantId = loginUser.getTenantId();
+                if (tenantId != null) {
+                    String tenantKey = "tenant:" + tenantId;
+                    DynamicDataSourceContextHolder.setDataSourceType(tenantKey);
+                } else {
+                    // 没有租户,回主库
+                    DynamicDataSourceContextHolder.setDataSourceType(DataSourceType.MASTER.name());
+                }
+
+                if(tenantId != null) {
+                    SysConfig cfg = sysConfigMapper.selectConfigByConfigKey("projectConfig");
+                    if (cfg != null && StringUtils.isNotBlank(cfg.getConfigValue())) {
+                        TenantConfigContext.set(JSONObject.parseObject(cfg.getConfigValue()));
+                    } else {
+                        TenantConfigContext.set(null);
+                    }
+
+                    WxMpProperties.loadTenantConfigsFromContext();
+                }
+
+
+                tokenService.verifyToken(loginUser);
+                UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken(loginUser, null, loginUser.getAuthorities());
+                authenticationToken.setDetails(new WebAuthenticationDetailsSource().buildDetails(request));
+                SecurityContextHolder.getContext().setAuthentication(authenticationToken);
+            }
+            chain.doFilter(request, response);
+        } finally {
+//            List<WxMpProperties.MpConfig> configs = wxMpProperties.getConfigs();
+//            for (WxMpProperties.MpConfig cfg : configs) {
+//                System.out.println("当前租户公众号 AppId = " + cfg.getAppId());
+//                System.out.println("当前租户公众号 Secret = " + cfg.getSecret());
+//                System.out.println("当前租户公众号 Token = " + cfg.getToken());
+//                System.out.println("当前租户公众号 AesKey = " + cfg.getAesKey());
+//            }
+
+            WxMpProperties.clearTenantConfigs();
+            TenantConfigContext.clear();
+            DynamicDataSourceContextHolder.clearDataSourceType();
         }
-        chain.doFilter(request, response);
     }
 }

+ 159 - 89
fs-company/src/main/java/com/fs/framework/service/CompanyLoginService.java

@@ -1,11 +1,13 @@
 package com.fs.framework.service;
 
+import cn.hutool.core.bean.BeanUtil;
 import cn.hutool.core.util.ObjectUtil;
 import cn.hutool.http.HttpUtil;
 import com.alibaba.fastjson.JSON;
 import com.alibaba.fastjson.JSONObject;
 import com.fs.common.constant.Constants;
 import com.fs.common.core.redis.RedisCache;
+import com.fs.common.enums.DataSourceType;
 import com.fs.common.exception.ServiceException;
 import com.fs.common.exception.user.CaptchaException;
 import com.fs.common.exception.user.CaptchaExpireException;
@@ -17,11 +19,15 @@ import com.fs.common.utils.StringUtils;
 import com.fs.common.utils.ip.IpUtils;
 import com.fs.company.domain.CompanyUser;
 import com.fs.company.service.ICompanyUserService;
+import com.fs.framework.datasource.DynamicDataSourceContextHolder;
+import com.fs.framework.datasource.TenantDataSourceManager;
 import com.fs.framework.manager.AsyncManager;
 import com.fs.framework.manager.factory.AsyncFactory;
 import com.fs.framework.security.LoginUser;
 import com.fs.his.domain.StoreLoginUser;
 import com.fs.system.service.ISysConfigService;
+import com.fs.system.service.ISysUserService;
+import com.fs.tenant.domain.TenantInfo;
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.beans.factory.annotation.Value;
@@ -72,6 +78,8 @@ public class CompanyLoginService
 
     @Autowired
     private UserDetailsService userDetailsService;
+    @Autowired
+    private ISysUserService userService;
 
     /**
      * 登录验证
@@ -82,7 +90,7 @@ public class CompanyLoginService
      * @param uuid 唯一标识
      * @return 结果
      */
-    public String login(String username, String password, String code, String uuid)
+    public String login(String username, String password, String code, String uuid,String tenantCode)
     {
         String verifyKey = Constants.CAPTCHA_CODE_KEY + uuid;
         String captcha = redisCache.getCacheObject(verifyKey);
@@ -97,117 +105,179 @@ public class CompanyLoginService
             AsyncManager.me().execute(AsyncFactory.recordLogininfor(0l,username, Constants.LOGIN_FAIL, MessageUtils.message("user.jcaptcha.error")));
             throw new CaptchaException();
         }
-        // 用户验证
-        Authentication authentication = null;
-        try
+
+        TenantInfo tenantInfo = null;
+
+        // 默认使用主库
+        DynamicDataSourceContextHolder.setDataSourceType(DataSourceType.MASTER.name());
+
+        // ===== 只有传了 tenantCode 才查询租户并切库 =====
+        if (StringUtils.isNotBlank(tenantCode))
         {
-            // 该方法会去调用UserDetailsServiceImpl.loadUserByUsername
-            authentication = authenticationManager
-                    .authenticate(new UsernamePasswordAuthenticationToken(username, password));
+            // 查询租户(主库)
+            tenantInfo = userService.getTenantInfo(tenantCode);
+            if (BeanUtil.isEmpty(tenantInfo)) {
+                throw new ServiceException("企业不存在");
+            }
+
+            if (!tenantInfo.getStatus().equals(1)) {
+                throw new ServiceException("企业已禁用");
+            }
+
+            // 切租户库
+            tenantDataSourceManager.switchTenant(tenantInfo);
         }
-        catch (Exception e)
-        {
-            if (e instanceof BadCredentialsException)
+
+        try {
+            // 用户验证
+            Authentication authentication = null;
+            try
             {
-                AsyncManager.me().execute(AsyncFactory.recordLogininfor(0l,username, Constants.LOGIN_FAIL, MessageUtils.message("user.password.not.match")));
-                throw new UserPasswordNotMatchException();
+                // 该方法会去调用UserDetailsServiceImpl.loadUserByUsername
+                authentication = authenticationManager
+                        .authenticate(new UsernamePasswordAuthenticationToken(username, password));
             }
-            else
+            catch (Exception e)
             {
-                AsyncManager.me().execute(AsyncFactory.recordLogininfor(0l,username, Constants.LOGIN_FAIL, e.getMessage()));
-                throw new ServiceException(e.getMessage());
+                if (e instanceof BadCredentialsException)
+                {
+                    AsyncManager.me().execute(AsyncFactory.recordLogininfor(0l,username, Constants.LOGIN_FAIL, MessageUtils.message("user.password.not.match")));
+                    throw new UserPasswordNotMatchException();
+                }
+                else
+                {
+                    AsyncManager.me().execute(AsyncFactory.recordLogininfor(0l,username, Constants.LOGIN_FAIL, e.getMessage()));
+                    throw new ServiceException(e.getMessage());
+                }
             }
-        }
-        LoginUser loginUser = (LoginUser) authentication.getPrincipal();
-        //查询当前登录用户信息
-        CompanyUser companyUser = companyUserService.selectCompanyUserById(loginUser.getUser().getUserId());
-        AsyncManager.me().execute(AsyncFactory.recordLogininfor(loginUser.getUser().getCompanyId(),username, Constants.LOGIN_SUCCESS, MessageUtils.message("user.login.success")));
-        redisCache.setCacheObject("companyId:"+loginUser.getUser().getUserId(),loginUser.getUser().getCompanyId(),604800, TimeUnit.SECONDS);
-        String ipAddr = IpUtils.getIpAddr(ServletUtils.getRequest()).split(",")[0].trim();
-        log.info("销售用户{}正常登录获取到的ip地址{}", loginUser.getUser().getUserId(), ipAddr);
-
-        companyUser.setUserId(loginUser.getUser().getUserId());
-        String loginIp = companyUser.getLoginIp();
-        List<String> ipList = new ArrayList<>();
-        if (StringUtils.isNotEmpty(loginIp)) {
-            String[] ips = loginIp.split(",");
-            for (String ip : ips) {
-                ip = ip.trim();                  // 去掉前后空格
-                if (!ip.isEmpty()) {
-                    ipList.add(ip);              // 先加入已有 IP
+            LoginUser loginUser = (LoginUser) authentication.getPrincipal();
+            //查询当前登录用户信息
+            CompanyUser companyUser = companyUserService.selectCompanyUserById(loginUser.getUser().getUserId());
+            AsyncManager.me().execute(AsyncFactory.recordLogininfor(loginUser.getUser().getCompanyId(),username, Constants.LOGIN_SUCCESS, MessageUtils.message("user.login.success")));
+            redisCache.setCacheObject("companyId:"+loginUser.getUser().getUserId(),loginUser.getUser().getCompanyId(),604800, TimeUnit.SECONDS);
+            String ipAddr = IpUtils.getIpAddr(ServletUtils.getRequest()).split(",")[0].trim();
+            log.info("销售用户{}正常登录获取到的ip地址{}", loginUser.getUser().getUserId(), ipAddr);
+
+            companyUser.setUserId(loginUser.getUser().getUserId());
+            String loginIp = companyUser.getLoginIp();
+            List<String> ipList = new ArrayList<>();
+            if (StringUtils.isNotEmpty(loginIp)) {
+                String[] ips = loginIp.split(",");
+                for (String ip : ips) {
+                    ip = ip.trim();                  // 去掉前后空格
+                    if (!ip.isEmpty()) {
+                        ipList.add(ip);              // 先加入已有 IP
+                    }
                 }
             }
-        }
 
-        ipList.add(ipAddr);
-        List<String> distinctList = ipList.stream()
-                .map(String::trim)       // 再次确保去掉空格
-                .distinct()
-                .collect(Collectors.toList());
-        companyUser.setLoginIp(String.join(",", distinctList));
-
-        companyUser.setLoginDate(new Date());
-        companyUserService.updateCompanyUser(companyUser);
-        // 生成token
-        return tokenService.createToken(loginUser);
-    }
+            ipList.add(ipAddr);
+            List<String> distinctList = ipList.stream()
+                    .map(String::trim)       // 再次确保去掉空格
+                    .distinct()
+                    .collect(Collectors.toList());
+            companyUser.setLoginIp(String.join(",", distinctList));
 
+            companyUser.setLoginDate(new Date());
+            companyUserService.updateCompanyUser(companyUser);
+            // 只有多租户登录才设置 tenantId
+            if (tenantInfo != null) {
+                loginUser.setTenantId(tenantInfo.getId());
+            }
+            // 生成token
+            return tokenService.createToken(loginUser);
+        } finally {
+            // 防止线程串库(必须)
+            tenantDataSourceManager.clear();
+            DynamicDataSourceContextHolder.setDataSourceType(DataSourceType.MASTER.name());
+        }
+    }
 
-    public boolean checkIsNeedCheck(String username, String password, String code, String uuid)
+    @Resource
+    private TenantDataSourceManager tenantDataSourceManager;
+    public boolean checkIsNeedCheck(String username, String password, String code, String uuid, String tenantCode)
     {
-        String verifyKey = Constants.CAPTCHA_CODE_KEY + uuid;
-        String captcha = redisCache.getCacheObject(verifyKey);
-        //redisCache.deleteObject(verifyKey);
-        if (captcha == null)
-        {
-            AsyncManager.me().execute(AsyncFactory.recordLogininfor(0l,username, Constants.LOGIN_FAIL, MessageUtils.message("user.jcaptcha.expire")));
-            throw new CaptchaExpireException();
-        }
-        if (!code.equalsIgnoreCase(captcha))
-        {
-            AsyncManager.me().execute(AsyncFactory.recordLogininfor(0l,username, Constants.LOGIN_FAIL, MessageUtils.message("user.jcaptcha.error")));
-            throw new CaptchaException();
-        }
-        // 用户验证
-        Authentication authentication = null;
-        try
-        {
-            // 该方法会去调用UserDetailsServiceImpl.loadUserByUsername
-            authentication = authenticationManager
-                    .authenticate(new UsernamePasswordAuthenticationToken(username, password));
-        }
-        catch (Exception e)
+        TenantInfo tenantInfo = null;
+        // (查租户)
+        DynamicDataSourceContextHolder.setDataSourceType(DataSourceType.MASTER.name());
+
+        // ===== 只有传了 tenantCode 才走租户逻辑 =====
+        if (StringUtils.isNotBlank(tenantCode))
         {
-            if (e instanceof BadCredentialsException)
+            // 查询租户(主库)
+            tenantInfo = userService.getTenantInfo(tenantCode);
+            if (BeanUtil.isEmpty(tenantInfo))
             {
-                AsyncManager.me().execute(AsyncFactory.recordLogininfor(0l,username, Constants.LOGIN_FAIL, MessageUtils.message("user.password.not.match")));
-                throw new UserPasswordNotMatchException();
+                throw new ServiceException("企业不存在");
             }
-            else
+            if (!tenantInfo.getStatus().equals(1))
             {
-                AsyncManager.me().execute(AsyncFactory.recordLogininfor(0l,username, Constants.LOGIN_FAIL, e.getMessage()));
-                throw new ServiceException(e.getMessage());
+                throw new ServiceException("企业已禁用");
             }
+
+            // 切到租户库
+            tenantDataSourceManager.switchTenant(tenantInfo);
         }
-        LoginUser loginUser = (LoginUser) authentication.getPrincipal();
-        //查询当前登录用户信息
-        CompanyUser companyUser = companyUserService.selectCompanyUserById(loginUser.getUser().getUserId());
 
-        Long[] userIds = new Long[]{2020L};
-        for (Long userId : userIds) {
-            if (userId.equals(companyUser.getUserId())) {
+        try {
+            String verifyKey = Constants.CAPTCHA_CODE_KEY + uuid;
+            String captcha = redisCache.getCacheObject(verifyKey);
+            //redisCache.deleteObject(verifyKey);
+            if (captcha == null)
+            {
+                AsyncManager.me().execute(AsyncFactory.recordLogininfor(0l,username, Constants.LOGIN_FAIL, MessageUtils.message("user.jcaptcha.expire")));
+                throw new CaptchaExpireException();
+            }
+            if (!code.equalsIgnoreCase(captcha))
+            {
+                AsyncManager.me().execute(AsyncFactory.recordLogininfor(0l,username, Constants.LOGIN_FAIL, MessageUtils.message("user.jcaptcha.error")));
+                throw new CaptchaException();
+            }
+            // 用户验证
+            Authentication authentication = null;
+            try
+            {
+                // 该方法会去调用UserDetailsServiceImpl.loadUserByUsername
+                authentication = authenticationManager
+                        .authenticate(new UsernamePasswordAuthenticationToken(username, password));
+            }
+            catch (Exception e)
+            {
+                if (e instanceof BadCredentialsException)
+                {
+                    AsyncManager.me().execute(AsyncFactory.recordLogininfor(0l,username, Constants.LOGIN_FAIL, MessageUtils.message("user.password.not.match")));
+                    throw new UserPasswordNotMatchException();
+                }
+                else
+                {
+                    AsyncManager.me().execute(AsyncFactory.recordLogininfor(0l,username, Constants.LOGIN_FAIL, e.getMessage()));
+                    throw new ServiceException(e.getMessage());
+                }
+            }
+            LoginUser loginUser = (LoginUser) authentication.getPrincipal();
+            //查询当前登录用户信息
+            CompanyUser companyUser = companyUserService.selectCompanyUserById(loginUser.getUser().getUserId());
+
+            Long[] userIds = new Long[]{2020L};
+            for (Long userId : userIds) {
+                if (userId.equals(companyUser.getUserId())) {
+                    return false;
+                }
+            }
+
+            // 判断是否开启了扫码配置
+            if (ObjectUtil.isEmpty(isNeedScan) || !isNeedScan){
                 return false;
             }
-        }
 
-        // 判断是否开启了扫码配置
-        if (ObjectUtil.isEmpty(isNeedScan) || !isNeedScan){
-            return false;
+            //true → 要发短信验证码再登录
+            //false → 直接登录
+            return needCheck(companyUser);
+        } finally {
+            // 防止线程串库
+            tenantDataSourceManager.clear();
+            DynamicDataSourceContextHolder.setDataSourceType(DataSourceType.MASTER.name());
         }
-
-        //true → 要发短信验证码再登录
-        //false → 直接登录
-        return needCheck(companyUser);
     }
 
     public boolean needCheck(CompanyUser companyUser) {

+ 9 - 7
fs-framework/src/main/java/com/fs/framework/security/filter/JwtAuthenticationTokenFilter.java

@@ -62,14 +62,16 @@ public class JwtAuthenticationTokenFilter extends OncePerRequestFilter
                     DynamicDataSourceContextHolder.setDataSourceType(DataSourceType.MASTER.name());
                 }
 
-                SysConfig cfg = sysConfigMapper.selectConfigByConfigKey("projectConfig");
-                if (cfg != null && StringUtils.isNotBlank(cfg.getConfigValue())) {
-                    TenantConfigContext.set(JSONObject.parseObject(cfg.getConfigValue()));
-                } else {
-                    TenantConfigContext.set(null);
-                }
+                if (tenantId != null) {
+                    SysConfig cfg = sysConfigMapper.selectConfigByConfigKey("projectConfig");
+                    if (cfg != null && StringUtils.isNotBlank(cfg.getConfigValue())) {
+                        TenantConfigContext.set(JSONObject.parseObject(cfg.getConfigValue()));
+                    } else {
+                        TenantConfigContext.set(null);
+                    }
 
-                WxMpProperties.loadTenantConfigsFromContext();
+                    WxMpProperties.loadTenantConfigsFromContext();
+                }
 
                 tokenService.verifyToken(loginUser);