update: 同步 RuoYi-Vue-Plus(v4.7.0) 更新
This commit is contained in:
@@ -76,6 +76,14 @@ public interface SysUserMapper extends BaseMapperPlus<SysUserMapper, SysUser, Sy
|
||||
*/
|
||||
SysUser selectUserByPhonenumber(String phonenumber);
|
||||
|
||||
/**
|
||||
* 通过邮箱查询用户
|
||||
*
|
||||
* @param email 邮箱
|
||||
* @return 用户对象信息
|
||||
*/
|
||||
SysUser selectUserByEmail(String email);
|
||||
|
||||
/**
|
||||
* 通过用户ID查询用户
|
||||
*
|
||||
|
||||
@@ -176,4 +176,6 @@ public interface ISysRoleService {
|
||||
* @return 结果
|
||||
*/
|
||||
int insertAuthUsers(Long roleId, Long[] userIds);
|
||||
|
||||
void cleanOnlineUserByRole(Long roleId);
|
||||
}
|
||||
|
||||
@@ -32,7 +32,6 @@ import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import java.time.Duration;
|
||||
import java.util.List;
|
||||
import java.util.function.Supplier;
|
||||
@@ -67,11 +66,10 @@ public class SysLoginService {
|
||||
* @return 结果
|
||||
*/
|
||||
public String login(String username, String password, String code, String uuid) {
|
||||
HttpServletRequest request = ServletUtils.getRequest();
|
||||
boolean captchaEnabled = configService.selectCaptchaEnabled();
|
||||
// 验证码开关
|
||||
if (captchaEnabled) {
|
||||
validateCaptcha(username, code, uuid, request);
|
||||
validateCaptcha(username, code, uuid);
|
||||
}
|
||||
SysUser user = loadUserByUsername(username);
|
||||
checkLogin(LoginType.PASSWORD, username, () -> !BCrypt.checkpw(password, user.getPassword()));
|
||||
@@ -100,6 +98,20 @@ public class SysLoginService {
|
||||
return StpUtil.getTokenValue();
|
||||
}
|
||||
|
||||
public String emailLogin(String email, String emailCode) {
|
||||
// 通过手机号查找用户
|
||||
SysUser user = loadUserByEmail(email);
|
||||
|
||||
checkLogin(LoginType.EMAIL, user.getUserName(), () -> !validateEmailCode(email, emailCode));
|
||||
// 此处可根据登录用户的数据不同 自行创建 loginUser
|
||||
LoginUser loginUser = buildLoginUser(user);
|
||||
// 生成token
|
||||
LoginHelper.loginByDevice(loginUser, DeviceType.APP);
|
||||
|
||||
recordLogininfor(user.getUserName(), Constants.LOGIN_SUCCESS, MessageUtils.message("user.login.success"));
|
||||
recordLoginInfo(user.getUserId(), user.getUserName());
|
||||
return StpUtil.getTokenValue();
|
||||
}
|
||||
|
||||
public String xcxLogin(String xcxCode) {
|
||||
// xcxCode 为 小程序调用 wx.login 授权后获取
|
||||
@@ -140,7 +152,6 @@ public class SysLoginService {
|
||||
* @param username 用户名
|
||||
* @param status 状态
|
||||
* @param message 消息内容
|
||||
* @return
|
||||
*/
|
||||
private void recordLogininfor(String username, String status, String message) {
|
||||
LogininforEvent logininforEvent = new LogininforEvent();
|
||||
@@ -163,6 +174,18 @@ public class SysLoginService {
|
||||
return code.equals(smsCode);
|
||||
}
|
||||
|
||||
/**
|
||||
* 校验邮箱验证码
|
||||
*/
|
||||
private boolean validateEmailCode(String email, String emailCode) {
|
||||
String code = RedisUtils.getCacheObject(CacheConstants.CAPTCHA_CODE_KEY + email);
|
||||
if (StringUtils.isBlank(code)) {
|
||||
recordLogininfor(email, Constants.LOGIN_FAIL, MessageUtils.message("user.jcaptcha.expire"));
|
||||
throw new CaptchaExpireException();
|
||||
}
|
||||
return code.equals(emailCode);
|
||||
}
|
||||
|
||||
/**
|
||||
* 校验验证码
|
||||
*
|
||||
@@ -170,7 +193,7 @@ public class SysLoginService {
|
||||
* @param code 验证码
|
||||
* @param uuid 唯一标识
|
||||
*/
|
||||
public void validateCaptcha(String username, String code, String uuid, HttpServletRequest request) {
|
||||
public void validateCaptcha(String username, String code, String uuid) {
|
||||
String verifyKey = CacheConstants.CAPTCHA_CODE_KEY + StringUtils.defaultString(uuid, "");
|
||||
String captcha = RedisUtils.getCacheObject(verifyKey);
|
||||
RedisUtils.deleteObject(verifyKey);
|
||||
@@ -212,6 +235,20 @@ public class SysLoginService {
|
||||
return userMapper.selectUserByPhonenumber(phonenumber);
|
||||
}
|
||||
|
||||
private SysUser loadUserByEmail(String email) {
|
||||
SysUser user = userMapper.selectOne(new LambdaQueryWrapper<SysUser>()
|
||||
.select(SysUser::getPhonenumber, SysUser::getStatus)
|
||||
.eq(SysUser::getEmail, email));
|
||||
if (ObjectUtil.isNull(user)) {
|
||||
log.info("登录用户:{} 不存在.", email);
|
||||
throw new UserException("user.not.exists", email);
|
||||
} else if (UserStatus.DISABLE.getCode().equals(user.getStatus())) {
|
||||
log.info("登录用户:{} 已被停用.", email);
|
||||
throw new UserException("user.blocked", email);
|
||||
}
|
||||
return userMapper.selectUserByEmail(email);
|
||||
}
|
||||
|
||||
private SysUser loadUserByOpenid(String openid) {
|
||||
// 使用 openid 查询绑定用户 如未绑定用户 则根据业务自行处理 例如 创建默认用户
|
||||
// todo 自行实现 userService.selectUserByOpenid(openid);
|
||||
|
||||
@@ -3,7 +3,6 @@ package com.ruoyi.system.service;
|
||||
import cn.dev33.satoken.secure.BCrypt;
|
||||
import com.ruoyi.common.constant.CacheConstants;
|
||||
import com.ruoyi.common.constant.Constants;
|
||||
import com.ruoyi.common.constant.UserConstants;
|
||||
import com.ruoyi.common.core.domain.event.LogininforEvent;
|
||||
import com.ruoyi.common.core.domain.entity.SysUser;
|
||||
import com.ruoyi.common.core.domain.model.RegisterBody;
|
||||
@@ -19,8 +18,6 @@ import com.ruoyi.common.utils.spring.SpringUtils;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
|
||||
/**
|
||||
* 注册校验方法
|
||||
*
|
||||
@@ -37,7 +34,6 @@ public class SysRegisterService {
|
||||
* 注册
|
||||
*/
|
||||
public void register(RegisterBody registerBody) {
|
||||
HttpServletRequest request = ServletUtils.getRequest();
|
||||
String username = registerBody.getUsername();
|
||||
String password = registerBody.getPassword();
|
||||
// 校验用户类型是否存在
|
||||
@@ -46,7 +42,7 @@ public class SysRegisterService {
|
||||
boolean captchaEnabled = configService.selectCaptchaEnabled();
|
||||
// 验证码开关
|
||||
if (captchaEnabled) {
|
||||
validateCaptcha(username, registerBody.getCode(), registerBody.getUuid(), request);
|
||||
validateCaptcha(username, registerBody.getCode(), registerBody.getUuid());
|
||||
}
|
||||
SysUser sysUser = new SysUser();
|
||||
sysUser.setUserName(username);
|
||||
@@ -70,9 +66,8 @@ public class SysRegisterService {
|
||||
* @param username 用户名
|
||||
* @param code 验证码
|
||||
* @param uuid 唯一标识
|
||||
* @return 结果
|
||||
*/
|
||||
public void validateCaptcha(String username, String code, String uuid, HttpServletRequest request) {
|
||||
public void validateCaptcha(String username, String code, String uuid) {
|
||||
String verifyKey = CacheConstants.CAPTCHA_CODE_KEY + StringUtils.defaultString(uuid, "");
|
||||
String captcha = RedisUtils.getCacheObject(verifyKey);
|
||||
RedisUtils.deleteObject(verifyKey);
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
package com.ruoyi.system.service.impl;
|
||||
|
||||
import cn.dev33.satoken.exception.NotLoginException;
|
||||
import cn.dev33.satoken.stp.StpUtil;
|
||||
import cn.hutool.core.collection.CollUtil;
|
||||
import cn.hutool.core.util.ObjectUtil;
|
||||
import com.baomidou.mybatisplus.core.conditions.Wrapper;
|
||||
@@ -10,6 +12,7 @@ import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import com.ruoyi.common.constant.UserConstants;
|
||||
import com.ruoyi.common.core.domain.PageQuery;
|
||||
import com.ruoyi.common.core.domain.entity.SysRole;
|
||||
import com.ruoyi.common.core.domain.model.LoginUser;
|
||||
import com.ruoyi.common.core.page.TableDataInfo;
|
||||
import com.ruoyi.common.exception.ServiceException;
|
||||
import com.ruoyi.common.helper.LoginHelper;
|
||||
@@ -70,7 +73,7 @@ public class SysRoleServiceImpl implements ISysRoleService {
|
||||
.like(StringUtils.isNotBlank(role.getRoleKey()), "r.role_key", role.getRoleKey())
|
||||
.between(params.get("beginTime") != null && params.get("endTime") != null,
|
||||
"r.create_time", params.get("beginTime"), params.get("endTime"))
|
||||
.orderByAsc("r.role_sort");
|
||||
.orderByAsc("r.role_sort").orderByAsc("r.create_time");
|
||||
return wrapper;
|
||||
}
|
||||
|
||||
@@ -362,9 +365,13 @@ public class SysRoleServiceImpl implements ISysRoleService {
|
||||
*/
|
||||
@Override
|
||||
public int deleteAuthUser(SysUserRole userRole) {
|
||||
return userRoleMapper.delete(new LambdaQueryWrapper<SysUserRole>()
|
||||
int rows = userRoleMapper.delete(new LambdaQueryWrapper<SysUserRole>()
|
||||
.eq(SysUserRole::getRoleId, userRole.getRoleId())
|
||||
.eq(SysUserRole::getUserId, userRole.getUserId()));
|
||||
if (rows > 0) {
|
||||
cleanOnlineUserByRole(userRole.getRoleId());
|
||||
}
|
||||
return rows;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -376,9 +383,13 @@ public class SysRoleServiceImpl implements ISysRoleService {
|
||||
*/
|
||||
@Override
|
||||
public int deleteAuthUsers(Long roleId, Long[] userIds) {
|
||||
return userRoleMapper.delete(new LambdaQueryWrapper<SysUserRole>()
|
||||
int rows = userRoleMapper.delete(new LambdaQueryWrapper<SysUserRole>()
|
||||
.eq(SysUserRole::getRoleId, roleId)
|
||||
.in(SysUserRole::getUserId, Arrays.asList(userIds)));
|
||||
if (rows > 0) {
|
||||
cleanOnlineUserByRole(roleId);
|
||||
}
|
||||
return rows;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -401,6 +412,32 @@ public class SysRoleServiceImpl implements ISysRoleService {
|
||||
if (CollUtil.isNotEmpty(list)) {
|
||||
rows = userRoleMapper.insertBatch(list) ? list.size() : 0;
|
||||
}
|
||||
if (rows > 0) {
|
||||
cleanOnlineUserByRole(roleId);
|
||||
}
|
||||
return rows;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void cleanOnlineUserByRole(Long roleId) {
|
||||
List<String> keys = StpUtil.searchTokenValue("", 0, -1, false);
|
||||
if (CollUtil.isEmpty(keys)) {
|
||||
return;
|
||||
}
|
||||
// 角色关联的在线用户量过大会导致redis阻塞卡顿 谨慎操作
|
||||
keys.parallelStream().forEach(key -> {
|
||||
String token = StringUtils.substringAfterLast(key, ":");
|
||||
// 如果已经过期则跳过
|
||||
if (StpUtil.stpLogic.getTokenActivityTimeoutByToken(token) < -1) {
|
||||
return;
|
||||
}
|
||||
LoginUser loginUser = LoginHelper.getLoginUser(token);
|
||||
if (loginUser.getRoles().stream().anyMatch(r -> r.getRoleId().equals(roleId))) {
|
||||
try {
|
||||
StpUtil.logoutByTokenValue(token);
|
||||
} catch (NotLoginException ignored) {
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user