修改登录-添加先排除网格员
This commit is contained in:
@@ -1,5 +1,7 @@
|
||||
package com.ruoyi.cms.util;
|
||||
|
||||
import com.ruoyi.common.utils.StringUtils;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
@@ -138,18 +140,6 @@ public class StringUtil {
|
||||
.collect(Collectors.toList()); // 收集为List
|
||||
}
|
||||
|
||||
/**
|
||||
* 脱敏逻辑:前4位 + ***+ 后4位
|
||||
* @param idCard
|
||||
* @return
|
||||
*/
|
||||
public static String desensitizeIdCard(String idCard) {
|
||||
if (idCard == null || idCard.length() != 18) {
|
||||
return idCard; // 非标准身份证号不脱敏(或按规则处理)
|
||||
}
|
||||
return idCard.substring(0, 4) + "***" + idCard.substring(14);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取附件地址
|
||||
* @return
|
||||
@@ -183,4 +173,44 @@ public class StringUtil {
|
||||
}
|
||||
return request.getHeader("X-Proxy-Server");
|
||||
}
|
||||
|
||||
/**
|
||||
* 手机号脱敏
|
||||
* @param phone
|
||||
* @return
|
||||
*/
|
||||
public static String desensitizePhone(String phone) {
|
||||
if (StringUtils.isEmpty(phone) || phone.length() != 11) {
|
||||
return phone;
|
||||
}
|
||||
return phone.replaceAll("(\\d{3})\\d{4}(\\d{4})", "$1****$2");
|
||||
}
|
||||
|
||||
/**
|
||||
* 脱敏逻辑:前4位 + ***+ 后4位
|
||||
* @param idCard
|
||||
* @return
|
||||
*/
|
||||
public static String desensitizeIdCard(String idCard) {
|
||||
if (StringUtils.isEmpty(idCard)) {
|
||||
return null;
|
||||
}
|
||||
// 处理18位身份证(支持末尾X/x)
|
||||
if (idCard.matches("\\d{17}[\\dXx]")) {
|
||||
return idCard.replaceAll("(\\d{6})\\d{8}([\\dXx]{4})", "$1********$2");
|
||||
}
|
||||
// 处理15位身份证
|
||||
else if (idCard.matches("\\d{15}")) {
|
||||
return idCard.replaceAll("(\\d{6})\\d{6}(\\d{3})", "$1******$2");
|
||||
}
|
||||
// 非标准格式(如16位、含特殊字符):返回部分脱敏(前4位+****+后2位),避免明文暴露
|
||||
else {
|
||||
int len = idCard.length();
|
||||
if (len >= 6) {
|
||||
return idCard.substring(0, 4) + "****" + idCard.substring(len - 2);
|
||||
}
|
||||
// 长度过短(<6位):直接返回***,避免明文
|
||||
return "***";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -208,4 +208,44 @@ public class DistributedLockUtil {
|
||||
String identifier = acquireLockWithRenewal(lockKey);
|
||||
return new AutoReleaseLock(this, lockKey, identifier);
|
||||
}
|
||||
|
||||
/**
|
||||
* 锁+超时时间
|
||||
* @param lockKey
|
||||
* @param timeout
|
||||
* @param unit
|
||||
* @return
|
||||
*/
|
||||
public AutoReleaseLock tryLock(String lockKey, long timeout, TimeUnit unit) {
|
||||
// 1. 校验参数合法性(防御性编程)
|
||||
if (lockKey == null || lockKey.trim().isEmpty()) {
|
||||
throw new IllegalArgumentException("锁key不能为空");
|
||||
}
|
||||
if (timeout < 0) {
|
||||
throw new IllegalArgumentException("超时时间不能为负数");
|
||||
}
|
||||
if (unit == null) {
|
||||
throw new IllegalArgumentException("时间单位不能为空");
|
||||
}
|
||||
|
||||
// 2. 带超时获取锁(核心逻辑,需实现 acquireLockWithTimeout 方法)
|
||||
String identifier = acquireLockWithTimeout(lockKey, timeout, unit);
|
||||
|
||||
// 3. 返回自动释放锁(复用原有 AutoReleaseLock,无需修改)
|
||||
return new AutoReleaseLock(this, lockKey, identifier);
|
||||
}
|
||||
|
||||
/**
|
||||
* 带超时时间获取锁(支持自定义超时单位)
|
||||
* @param lockKey 锁键
|
||||
* @param timeout 获取锁的超时时间
|
||||
* @param unit 时间单位
|
||||
* @return 锁标识(获取失败返回null)
|
||||
*/
|
||||
public String acquireLockWithTimeout(String lockKey, long timeout, TimeUnit unit) {
|
||||
// 转换超时时间为秒(向上取整避免精度丢失)
|
||||
long acquireTimeoutSeconds = (long) Math.ceil((double) unit.toMillis(timeout) / 1000);
|
||||
// 使用默认的锁过期时间(30秒),也可根据需要改为让调用方传入
|
||||
return acquireLockWithRenewal(lockKey, DEFAULT_EXPIRE_SECONDS, acquireTimeoutSeconds);
|
||||
}
|
||||
}
|
||||
@@ -285,6 +285,7 @@ public class OauthLoginHlwService {
|
||||
appUserParm.setPhone(wwTyInfo.getPhone());
|
||||
appUserParm.setIdCard(wwTyInfo.getIdno());
|
||||
appUserParm.setName(wwTyInfo.getName());
|
||||
appUserParm.setIsCompanyUser(StringUtil.IS_JOB_REQUEST_USER);
|
||||
code=wwTyInfo.getIdno();
|
||||
break;
|
||||
default:
|
||||
@@ -294,9 +295,11 @@ public class OauthLoginHlwService {
|
||||
//企业联系人->现根据社会信用代码查询企业信息
|
||||
updateCompanyContact(wwTyInfo);
|
||||
//移动端
|
||||
appUserParm.setPhone(wwTyInfo.getPhone());
|
||||
String phone = StringUtils.isNotBlank(wwTyInfo.getPhone()) ? wwTyInfo.getPhone() : wwTyInfo.getContactphone();
|
||||
appUserParm.setPhone(phone);
|
||||
appUserParm.setIdCard(wwTyInfo.getEnterprisecode());
|
||||
appUserParm.setName(wwTyInfo.getEnterprisename());
|
||||
appUserParm.setIsCompanyUser(StringUtil.IS_COMPANY_USER);
|
||||
code=wwTyInfo.getEnterprisecode();
|
||||
}
|
||||
String localUsername=StringUtil.USER_KEY+code;
|
||||
|
||||
@@ -43,6 +43,7 @@ import com.ruoyi.system.service.ISysUserService;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import java.util.Date;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
/**
|
||||
* 登录校验方法
|
||||
@@ -321,41 +322,68 @@ public class SysLoginService
|
||||
|
||||
/**
|
||||
* 小程序登录主逻辑
|
||||
* 核心逻辑:优先处理网格员(is_company_user=2),再处理普通招聘者/求职者
|
||||
*/
|
||||
public AjaxResult appLoginNew(LoginBody dto) {
|
||||
//1.验证基础参数
|
||||
// 1. 验证基础参数(前端userType仅0/1,拦截非法参数)
|
||||
AjaxResult validateResult = validateBaseParam(dto);
|
||||
if (validateResult != null) {
|
||||
return validateResult;
|
||||
}
|
||||
|
||||
try {
|
||||
//2. 微信授权获取OpenID/UnionID/SessionKey
|
||||
// 2. 微信授权获取OpenID/UnionID/SessionKey(网格员查询依赖OpenID)
|
||||
WechatAuthVO wechatAuthVO = getWechatAuthInfo(dto.getCode());
|
||||
if (wechatAuthVO == null) {
|
||||
System.err.println("小程序登录失败:微信授权返回null");
|
||||
return AjaxResult.error("微信授权失败");
|
||||
}
|
||||
String openid = wechatAuthVO.getOpenid();
|
||||
String unionid = wechatAuthVO.getUnionid();
|
||||
String sessionKey = wechatAuthVO.getSessionKey();
|
||||
|
||||
String userType = dto.getUserType();
|
||||
//3. 优先匹配「OpenID+角色」的老用户
|
||||
AppUser existingUser = appUserService.selectByOpenid(openid,userType);
|
||||
if (existingUser != null) {
|
||||
return handleExistingUser(existingUser, userType);
|
||||
if (StringUtils.isEmpty(openid)) {
|
||||
System.err.println("小程序登录失败:微信授权返回openid为空");
|
||||
return AjaxResult.error("微信授权失败");
|
||||
}
|
||||
|
||||
// 4. 解密获取手机号(含二次校验)
|
||||
// 3. 第一步:通过OpenID优先查询网格员(无需解密手机号,效率更高)
|
||||
AppUser openidSpecialUser = appUserService.selectByOpenid(openid, StringUtil.IS_GRID_USER);
|
||||
if (openidSpecialUser != null) {
|
||||
System.out.printf("小程序登录-匹配到OpenID网格员:openid=%s, phone=%s%n",
|
||||
openidSpecialUser.getOpenid(), openidSpecialUser.getPhone());
|
||||
return handleSpecialUserLogin(openidSpecialUser);
|
||||
}
|
||||
|
||||
// 4. 解密获取手机号(含二次校验)- 网格员兜底查询/普通用户登录依赖
|
||||
String phone = decryptPhone(dto, sessionKey);
|
||||
if (phone == null) {
|
||||
System.err.println("小程序登录失败:手机号解密失败,openid=" + openid);
|
||||
return AjaxResult.error("获取手机号失败");
|
||||
}
|
||||
|
||||
// 5. 处理用户匹配与注册(核心逻辑拆分到独立方法)
|
||||
// 5. 第二步:通过手机号查询网格员(OpenID未匹配时兜底)
|
||||
AppUser phoneSpecialUser = appUserService.getPhoneAndUserType(phone, StringUtil.IS_GRID_USER);
|
||||
if (phoneSpecialUser != null) {
|
||||
System.out.printf("小程序登录-匹配到手机号网格员:phone=%s, openid=%s%n",
|
||||
phoneSpecialUser.getPhone(), phoneSpecialUser.getOpenid());
|
||||
return handleSpecialUserLogin(phoneSpecialUser);
|
||||
}
|
||||
|
||||
// 6. 非网格员:处理普通用户(招聘者/求职者)登录逻辑
|
||||
String userType = dto.getUserType();
|
||||
// 6.1 优先匹配「OpenID+前端传入角色」的老用户
|
||||
AppUser existingUser = appUserService.selectByOpenid(openid, userType);
|
||||
if (existingUser != null) {
|
||||
System.out.printf("小程序登录-匹配到普通老用户:openid=%s, userType=%s%n", openid, userType);
|
||||
return handleExistingUser(existingUser, userType);
|
||||
}
|
||||
|
||||
// 6.2 处理普通用户的匹配与注册(手机号绑定、新用户创建等)
|
||||
return handleUserMatchAndRegister(openid, unionid, phone, userType);
|
||||
|
||||
} catch (Exception e) {
|
||||
System.err.println("登录失败:" + e.getMessage());
|
||||
System.err.println("小程序登录异常:" + e.getMessage());
|
||||
e.printStackTrace();
|
||||
return AjaxResult.error("登录失败,请稍后重试");
|
||||
}
|
||||
}
|
||||
@@ -470,7 +498,7 @@ public class SysLoginService
|
||||
*/
|
||||
private AjaxResult handleNoRoleUserBinding(String openid, String unionid, String phone, String userType, AppUser noRoleUser) {
|
||||
String lockKey = "login_no_role_bind_" + phone + "_" + userType;
|
||||
try (DistributedLockUtil.AutoReleaseLock lock = distributedLockUtil.tryLock(lockKey)) {
|
||||
try (DistributedLockUtil.AutoReleaseLock lock = distributedLockUtil.tryLock(lockKey, 3, TimeUnit.SECONDS)) {
|
||||
if (!lock.isLocked()) {
|
||||
return AjaxResult.error("登录请求过于频繁,请稍后重试");
|
||||
}
|
||||
@@ -493,7 +521,7 @@ public class SysLoginService
|
||||
*/
|
||||
private AjaxResult handleNewUserRegistration(String openid, String unionid, String phone, String userType) {
|
||||
String createLockKey = "login_create_" + phone + "_" + userType;
|
||||
try (DistributedLockUtil.AutoReleaseLock lock = distributedLockUtil.tryLock(createLockKey)) {
|
||||
try (DistributedLockUtil.AutoReleaseLock lock = distributedLockUtil.tryLock(createLockKey, 3, TimeUnit.SECONDS)) {
|
||||
if (!lock.isLocked()) {
|
||||
return AjaxResult.error("登录请求过于频繁,请稍后重试");
|
||||
}
|
||||
@@ -506,6 +534,33 @@ public class SysLoginService
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 8-特殊处理-网格员登录
|
||||
* @param specialUser
|
||||
* @return
|
||||
*/
|
||||
private AjaxResult handleSpecialUserLogin(AppUser specialUser) {
|
||||
String lockKey = "login_grid_user_" + specialUser.getUserId(); // 按用户ID加锁
|
||||
try (DistributedLockUtil.AutoReleaseLock lock = distributedLockUtil.tryLock(lockKey, 2, TimeUnit.SECONDS)) {
|
||||
if (!lock.isLocked()) {
|
||||
System.err.println("网格员登录请求过于频繁,userId=" + specialUser.getUserId());
|
||||
return AjaxResult.error("登录请求过于频繁,请稍后重试");
|
||||
}
|
||||
// 原有逻辑(更新登录时间、生成token)
|
||||
AjaxResult ajax = AjaxResult.success();
|
||||
updateAppUserCommon(specialUser, null, null, null);
|
||||
String token = loginUserIdApp(specialUser);
|
||||
ajax.put(Constants.TOKEN, token);
|
||||
ajax.put("isNewUser", false);
|
||||
ajax.put("idCard", StringUtil.desensitizeIdCard(specialUser.getIdCard()));
|
||||
ajax.put("isCompanyUser", specialUser.getIsCompanyUser());
|
||||
System.out.printf("特殊角色用户登录成功,openid:%s, phone:%s, 角色:%s%n",
|
||||
specialUser.getOpenid(), StringUtil.desensitizePhone(specialUser.getPhone()), specialUser.getIsCompanyUser());
|
||||
System.out.println(ParamErrorConstants.LOG_AJAX_RETURN + JSON.toJSONString(ajax));
|
||||
return ajax;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理老用户登录(日志用println)
|
||||
*/
|
||||
|
||||
Reference in New Issue
Block a user