|
|
|
@ -30,10 +30,10 @@ import org.dromara.common.core.enums.UserType; |
|
|
|
import org.dromara.common.core.exception.base.BaseException; |
|
|
|
import org.dromara.common.core.utils.DateUtils; |
|
|
|
import org.dromara.common.core.utils.StringUtils; |
|
|
|
import org.dromara.common.redis.utils.RedisUtils; |
|
|
|
import org.dromara.common.satoken.utils.LoginHelper; |
|
|
|
import org.dromara.system.mapper.SysUserPostMapper; |
|
|
|
import org.dromara.system.mapper.SysUserRoleMapper; |
|
|
|
import org.redisson.api.RLock; |
|
|
|
import org.redisson.api.RedissonClient; |
|
|
|
import org.springframework.beans.factory.annotation.Autowired; |
|
|
|
import org.springframework.beans.factory.annotation.Value; |
|
|
|
@ -46,6 +46,7 @@ import java.util.Date; |
|
|
|
import java.util.HashMap; |
|
|
|
import java.util.Map; |
|
|
|
import java.util.UUID; |
|
|
|
import java.util.concurrent.TimeUnit; |
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
@ -107,34 +108,50 @@ public class AppEnterpriseLoginServiceImpl implements IAppEnterpriseLoginService |
|
|
|
@Autowired |
|
|
|
RuoYiConfig ruoYiConfig; |
|
|
|
|
|
|
|
@Value("${siq.mock.enabled:false}") |
|
|
|
private boolean mockEnabled; |
|
|
|
|
|
|
|
/** |
|
|
|
* 深i企用户登录并自动注册(带分布式锁防重) |
|
|
|
* 深i企用户登录并自动注册(带分布式锁防重,流程与一期 thirdLogin/siqLogin 一致) |
|
|
|
* |
|
|
|
* @param bo 登录参数 |
|
|
|
* @return 登录结果,包含token和用户信息 |
|
|
|
*/ |
|
|
|
@Override |
|
|
|
public Map<String, Object> siqLogin(AppEnterpriseLoginBo bo) { |
|
|
|
JSONObject userInfo; |
|
|
|
log.info("---> 深i企登录用户 code:{}", bo.getCode()); |
|
|
|
JSONObject userInfo = siqLoginInfo(bo); |
|
|
|
log.info("---> 深i企登录用户信息:{}", userInfo); |
|
|
|
log.info("---> 后面为本地登录的验证了!!! <---"); |
|
|
|
return doSiqLoginWithLock(userInfo); |
|
|
|
} |
|
|
|
|
|
|
|
if (mockEnabled) { |
|
|
|
log.info("使用模拟数据进行深i企登录测试"); |
|
|
|
userInfo = getMockSiqUserInfo(bo.getCode()); |
|
|
|
} else { |
|
|
|
userInfo = siqLoginInfo(bo); |
|
|
|
/** |
|
|
|
* 深i企模拟登录(开发/联调) |
|
|
|
*/ |
|
|
|
@Override |
|
|
|
public Map<String, Object> siqLoginMock(AppEnterpriseLoginBo bo) { |
|
|
|
log.info("---> 深i企模拟登录 userId:{}", bo.getUserId()); |
|
|
|
JSONObject userInfo = getMockSiqUserInfo(bo.getCode()); |
|
|
|
if (StringUtils.isNotEmpty(bo.getUserId())) { |
|
|
|
userInfo.put("userId", bo.getUserId()); |
|
|
|
} |
|
|
|
return doSiqLoginWithLock(userInfo); |
|
|
|
} |
|
|
|
|
|
|
|
String siqUserId = userInfo.getString("userId"); |
|
|
|
|
|
|
|
String lockKey = "siq_login_lock:" + siqUserId; |
|
|
|
/** |
|
|
|
* 加锁后完成用户注册、企业关联并签发 token |
|
|
|
*/ |
|
|
|
private Map<String, Object> doSiqLoginWithLock(JSONObject userInfo) { |
|
|
|
String lockKey = resolveLoginLockKey(userInfo); |
|
|
|
RLock lock = redissonClient.getLock("siq_login_lock:" + lockKey); |
|
|
|
boolean locked = false; |
|
|
|
try { |
|
|
|
log.info("深i企登录获取分布式锁成功: lockKey={}, userId={}", lockKey, siqUserId); |
|
|
|
locked = lock.tryLock(0, 1, TimeUnit.SECONDS); |
|
|
|
if (!locked) { |
|
|
|
log.info("用户正在登录中,用户信息:{}", userInfo.toJSONString()); |
|
|
|
throw new BaseException("用户正在登录中,请稍后再试"); |
|
|
|
} |
|
|
|
log.info("---> 登入锁 key: {}", lockKey); |
|
|
|
|
|
|
|
EnterpriseUser newUser = saveOrUpdateEnterpriseUser(userInfo); |
|
|
|
|
|
|
|
EnterpriseInformation enterpriseInformation = addSiqUserCompany(userInfo, newUser); |
|
|
|
|
|
|
|
if (newUser != null && enterpriseInformation != null) { |
|
|
|
@ -142,26 +159,49 @@ public class AppEnterpriseLoginServiceImpl implements IAppEnterpriseLoginService |
|
|
|
} |
|
|
|
|
|
|
|
String token = generateToken(newUser, enterpriseInformation); |
|
|
|
|
|
|
|
Map<String, Object> result = new HashMap<>(); |
|
|
|
result.put("token", token); |
|
|
|
result.put("userId", newUser.getUserId()); |
|
|
|
result.put("userName", newUser.getUserName()); |
|
|
|
result.put("loginName", newUser.getLoginName()); |
|
|
|
result.put("phonenumber", newUser.getPhonenumber() != null ? newUser.getPhonenumber() : ""); |
|
|
|
result.put("enterpriseId", enterpriseInformation.getId()); |
|
|
|
result.put("enterpriseName", enterpriseInformation.getEnterpriseName()); |
|
|
|
result.put("enterpriseNumber", enterpriseInformation.getEnterpriseNumber()); |
|
|
|
result.put("platformType", PlatformTypeEnums.ENTERPRISE.getKey()); |
|
|
|
|
|
|
|
return result; |
|
|
|
|
|
|
|
return buildLoginResult(newUser, enterpriseInformation, token); |
|
|
|
} catch (BaseException e) { |
|
|
|
throw e; |
|
|
|
} catch (InterruptedException e) { |
|
|
|
Thread.currentThread().interrupt(); |
|
|
|
throw new BaseException("登录处理被中断"); |
|
|
|
} catch (Exception e) { |
|
|
|
log.error("深i企登录处理异常: lockKey={}", lockKey, e); |
|
|
|
throw new BaseException("登录处理失败:" + e.getMessage()); |
|
|
|
} finally { |
|
|
|
if (locked && lock.isHeldByCurrentThread()) { |
|
|
|
lock.unlock(); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
/** |
|
|
|
* 与一期一致:优先使用 account 作为锁键,否则使用解密后的手机号 |
|
|
|
*/ |
|
|
|
private String resolveLoginLockKey(JSONObject userInfo) { |
|
|
|
String account = userInfo.getString("account"); |
|
|
|
if (StringUtils.isNotEmpty(account)) { |
|
|
|
return account; |
|
|
|
} |
|
|
|
return IdCardCryptoUtil.symmetricDecryptIdCard(secretKey, userInfo.getString("phone")); |
|
|
|
} |
|
|
|
|
|
|
|
private Map<String, Object> buildLoginResult(EnterpriseUser newUser, |
|
|
|
EnterpriseInformation enterpriseInformation, |
|
|
|
String token) { |
|
|
|
Map<String, Object> result = new HashMap<>(); |
|
|
|
result.put("token", token); |
|
|
|
result.put("userId", newUser.getUserId()); |
|
|
|
result.put("userName", newUser.getUserName()); |
|
|
|
result.put("loginName", newUser.getLoginName()); |
|
|
|
result.put("phonenumber", newUser.getPhonenumber() != null ? newUser.getPhonenumber() : ""); |
|
|
|
result.put("enterpriseId", enterpriseInformation.getId()); |
|
|
|
result.put("enterpriseName", enterpriseInformation.getEnterpriseName()); |
|
|
|
result.put("enterpriseNumber", enterpriseInformation.getEnterpriseNumber()); |
|
|
|
result.put("platformType", PlatformTypeEnums.ENTERPRISE.getKey()); |
|
|
|
return result; |
|
|
|
} |
|
|
|
|
|
|
|
/** |
|
|
|
* 保存或更新企业用户信息 |
|
|
|
* <p> |
|
|
|
@ -250,16 +290,18 @@ public class AppEnterpriseLoginServiceImpl implements IAppEnterpriseLoginService |
|
|
|
public JSONObject siqLoginInfo(AppEnterpriseLoginBo bo) { |
|
|
|
try { |
|
|
|
Map<String, Object> params = new HashMap<>(); |
|
|
|
|
|
|
|
log.info("调用深i企登录接口,参数: {}", bo); |
|
|
|
String accessKeySign = IdCardCryptoUtil.symmetricEncryptIdCard(secretKey, bo.getCode()); |
|
|
|
params.put("accessKeySign", accessKeySign); |
|
|
|
params.put("appCode", code); |
|
|
|
log.info("调用深i企登录接口,参数加密后: {}", params); |
|
|
|
|
|
|
|
String data = HttpUtil.httpSendPost( |
|
|
|
siqUrl + ApiConstants.API_SIQUSERLOGIN, |
|
|
|
JSONObject.toJSONString(params), |
|
|
|
new HashMap<>() |
|
|
|
); |
|
|
|
log.info("调用深i企登录接口响应: {}", data); |
|
|
|
|
|
|
|
JSONObject jsonObject = JSONObject.parseObject(data); |
|
|
|
JSONObject userInfo = jsonObject.getJSONObject("data"); |
|
|
|
@ -269,7 +311,7 @@ public class AppEnterpriseLoginServiceImpl implements IAppEnterpriseLoginService |
|
|
|
throw new BaseException("深i企接口返回数据异常"); |
|
|
|
} |
|
|
|
|
|
|
|
log.debug("深i企登录返回用户信息: userId={}", userInfo.getString("userId")); |
|
|
|
log.info("解析深i企登录接口响应成功,用户信息: {}", userInfo); |
|
|
|
return userInfo; |
|
|
|
|
|
|
|
} catch (BaseException e) { |
|
|
|
|