update: 同步 RuoYi-Vue-Plus(v4.7.0) 更新

This commit is contained in:
konbai
2023-05-19 23:11:59 +08:00
parent ae5fc22972
commit ddf4145bff
87 changed files with 785 additions and 333 deletions

View File

@@ -76,6 +76,14 @@ public interface SysUserMapper extends BaseMapperPlus<SysUserMapper, SysUser, Sy
*/
SysUser selectUserByPhonenumber(String phonenumber);
/**
* 通过邮箱查询用户
*
* @param email 邮箱
* @return 用户对象信息
*/
SysUser selectUserByEmail(String email);
/**
* 通过用户ID查询用户
*

View File

@@ -176,4 +176,6 @@ public interface ISysRoleService {
* @return 结果
*/
int insertAuthUsers(Long roleId, Long[] userIds);
void cleanOnlineUserByRole(Long roleId);
}

View File

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

View File

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

View File

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