|
|
@@ -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) {
|