This commit is contained in:
77
2024-05-18 01:02:13 +08:00
parent 874b33557d
commit 32933c2840
47 changed files with 416 additions and 282 deletions

View File

@@ -39,6 +39,7 @@ public interface ISysMenuService {
*/
Set<String> selectMenuPermsByUserId(Long userId);
/**
* 根据角色ID查询权限
*
@@ -62,6 +63,7 @@ public interface ISysMenuService {
* @return 选中菜单列表
*/
List<Long> selectMenuListByRoleId(Long roleId);
List<Long> selectMenuListByPackageId(Long packageId);
/**
* 构建前端路由所需要的菜单
@@ -134,4 +136,6 @@ public interface ISysMenuService {
* @return 结果
*/
boolean checkMenuNameUnique(SysMenu menu);
}

View File

@@ -8,9 +8,12 @@ import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.ruoyi.component.core.constant.CacheConstants;
import com.ruoyi.component.core.constant.Constants;
import com.ruoyi.component.core.constant.GlobalConstants;
import com.ruoyi.component.core.domain.dto.RoleDTO;
import com.ruoyi.component.log.event.LogininforEvent;
import com.ruoyi.component.redis.util.RedisUtils;
import com.ruoyi.component.tenant.core.TenantEntity;
import com.ruoyi.component.tenant.helper.TenantHelper;
import com.ruoyi.system.domain.SysUser;
import com.ruoyi.component.core.domain.model.LoginUser;
import com.ruoyi.component.core.domain.model.XcxLoginUser;
@@ -73,13 +76,13 @@ public class SysLoginService {
validateCaptcha(username, UserType.SYS_USER.getUserType(), code, uuid);
}
// 框架登录不限制从什么表查询 只要最终构建出 LoginUser 即可
SysUser user = loadUserByUsername(username);
SysUser user = TenantHelper.ignore(() -> loadUserByUsername(username));
checkLogin(LoginType.PASSWORD, username, () -> !BCrypt.checkpw(password, user.getPassword()));
// 此处可根据登录用户的数据不同 自行创建 loginUser 属性不够用继承扩展就行了
LoginUser loginUser = buildLoginUser(user);
// 生成token
LoginHelper.loginByDevice(loginUser, DeviceType.PC);
TenantHelper.setTenantId(loginUser.getTenantId());
recordLogininfor(username,loginUser.getUserType(), Constants.LOGIN_SUCCESS, MessageUtils.message("user.login.success"));
recordLoginInfo(user.getUserId(), username);
return StpUtil.getTokenValue();
@@ -175,7 +178,7 @@ public class SysLoginService {
* 校验短信验证码
*/
private boolean validateSmsCode(String phonenumber, String smsCode) {
String code = RedisUtils.getCacheObject(CacheConstants.CAPTCHA_CODE_KEY + phonenumber);
String code = RedisUtils.getCacheObject(GlobalConstants.CAPTCHA_CODE_KEY + phonenumber);
if (StringUtils.isBlank(code)) {
recordLogininfor(phonenumber, UserType.SYS_USER.getUserType(), Constants.LOGIN_FAIL, MessageUtils.message("user.jcaptcha.expire"));
throw new CaptchaExpireException();
@@ -187,7 +190,7 @@ public class SysLoginService {
* 校验邮箱验证码
*/
private boolean validateEmailCode(String email, String emailCode) {
String code = RedisUtils.getCacheObject(CacheConstants.CAPTCHA_CODE_KEY + email);
String code = RedisUtils.getCacheObject(GlobalConstants.CAPTCHA_CODE_KEY + email);
if (StringUtils.isBlank(code)) {
recordLogininfor(email, UserType.SYS_USER.getUserType(), Constants.LOGIN_FAIL, MessageUtils.message("user.jcaptcha.expire"));
throw new CaptchaExpireException();
@@ -203,7 +206,7 @@ public class SysLoginService {
* @param uuid 唯一标识
*/
public void validateCaptcha(String username, String userType, String code, String uuid) {
String verifyKey = CacheConstants.CAPTCHA_CODE_KEY + StringUtils.defaultString(uuid, "");
String verifyKey = GlobalConstants.CAPTCHA_CODE_KEY + StringUtils.defaultString(uuid, "");
String captcha = RedisUtils.getCacheObject(verifyKey);
RedisUtils.deleteObject(verifyKey);
if (captcha == null) {
@@ -218,7 +221,7 @@ public class SysLoginService {
private SysUser loadUserByUsername(String username) {
SysUser user = userMapper.selectOne(new LambdaQueryWrapper<SysUser>()
.select(SysUser::getUserName, SysUser::getStatus)
.select(SysUser::getUserName, SysUser::getStatus, SysUser::getTenantId)
.eq(SysUser::getUserName, username));
if (ObjectUtil.isNull(user)) {
log.info("登录用户:{} 不存在.", username);
@@ -232,7 +235,7 @@ public class SysLoginService {
private SysUser loadUserByPhonenumber(String phonenumber) {
SysUser user = userMapper.selectOne(new LambdaQueryWrapper<SysUser>()
.select(SysUser::getPhonenumber, SysUser::getStatus)
.select(SysUser::getPhonenumber, SysUser::getStatus, SysUser::getTenantId)
.eq(SysUser::getPhonenumber, phonenumber));
if (ObjectUtil.isNull(user)) {
log.info("登录用户:{} 不存在.", phonenumber);
@@ -246,7 +249,7 @@ public class SysLoginService {
private SysUser loadUserByEmail(String email) {
SysUser user = userMapper.selectOne(new LambdaQueryWrapper<SysUser>()
.select(SysUser::getPhonenumber, SysUser::getStatus)
.select(SysUser::getPhonenumber, SysUser::getStatus,SysUser::getTenantId)
.eq(SysUser::getEmail, email));
if (ObjectUtil.isNull(user)) {
log.info("登录用户:{} 不存在.", email);
@@ -283,6 +286,7 @@ public class SysLoginService {
loginUser.setUserType(user.getUserType());
loginUser.setMenuPermission(permissionService.getMenuPermission(user));
loginUser.setRolePermission(permissionService.getRolePermission(user));
loginUser.setTenantId(user.getTenantId());
loginUser.setDeptName(ObjectUtil.isNull(user.getDept()) ? "" : user.getDept().getDeptName());
List<RoleDTO> roles = BeanUtil.copyToList(user.getRoles(), RoleDTO.class);
loginUser.setRoles(roles);
@@ -307,7 +311,7 @@ public class SysLoginService {
* 登录校验
*/
private void checkLogin(LoginType loginType, String username, Supplier<Boolean> supplier) {
String errorKey = CacheConstants.PWD_ERR_CNT_KEY + username;
String errorKey = GlobalConstants.PWD_ERR_CNT_KEY + username;
String loginFail = Constants.LOGIN_FAIL;
// 获取用户登录错误次数默认为0 (可自定义限制策略 例如: key + username + ip)

View File

@@ -1,5 +1,6 @@
package com.ruoyi.system.service;
import com.ruoyi.component.core.constant.TenantConstants;
import com.ruoyi.system.domain.SysUser;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
@@ -29,7 +30,7 @@ public class SysPermissionService {
Set<String> roles = new HashSet<>();
// 管理员拥有所有权限
if (user.isAdmin()) {
roles.add("admin");
roles.add(TenantConstants.SUPER_ADMIN_ROLE_KEY);
} else {
roles.addAll(roleService.selectRolePermissionByUserId(user.getUserId()));
}

View File

@@ -3,6 +3,7 @@ package com.ruoyi.system.service;
import cn.dev33.satoken.secure.BCrypt;
import com.ruoyi.component.core.constant.CacheConstants;
import com.ruoyi.component.core.constant.Constants;
import com.ruoyi.component.core.constant.GlobalConstants;
import com.ruoyi.component.log.event.LogininforEvent;
import com.ruoyi.component.redis.util.RedisUtils;
import com.ruoyi.system.domain.SysUser;
@@ -68,7 +69,7 @@ public class SysRegisterService {
* @param uuid 唯一标识
*/
public void validateCaptcha(String username, String code, String uuid) {
String verifyKey = CacheConstants.CAPTCHA_CODE_KEY + StringUtils.defaultString(uuid, "");
String verifyKey = GlobalConstants.CAPTCHA_CODE_KEY + StringUtils.defaultString(uuid, "");
String captcha = RedisUtils.getCacheObject(verifyKey);
RedisUtils.deleteObject(verifyKey);
if (captcha == null) {

View File

@@ -8,6 +8,7 @@ import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ruoyi.component.core.constant.CacheConstants;
import com.ruoyi.component.core.constant.CacheNames;
import com.ruoyi.component.core.constant.GlobalConstants;
import com.ruoyi.component.core.constant.UserConstants;
import com.ruoyi.component.mybatis.core.page.PageQuery;
import com.ruoyi.component.mybatis.core.page.TableDataInfo;
@@ -235,10 +236,10 @@ public class SysDictTypeServiceImpl implements ISysDictTypeService, DictService
@Override
public String getDictLabel(String dictType, String dictValue, String separator) {
// 优先从本地缓存获取
List<SysDictData> datas = (List<SysDictData>) SaHolder.getStorage().get(CacheConstants.SYS_DICT_KEY + dictType);
List<SysDictData> datas = (List<SysDictData>) SaHolder.getStorage().get(GlobalConstants.SYS_DICT_KEY + dictType);
if (ObjectUtil.isNull(datas)) {
datas = SpringUtils.getAopProxy(this).selectDictDataByType(dictType);
SaHolder.getStorage().set(CacheConstants.SYS_DICT_KEY + dictType, datas);
SaHolder.getStorage().set(GlobalConstants.SYS_DICT_KEY + dictType, datas);
}
Map<String, String> map = StreamUtils.toMap(datas, SysDictData::getDictValue, SysDictData::getDictLabel);
@@ -263,10 +264,10 @@ public class SysDictTypeServiceImpl implements ISysDictTypeService, DictService
@Override
public String getDictValue(String dictType, String dictLabel, String separator) {
// 优先从本地缓存获取
List<SysDictData> datas = (List<SysDictData>) SaHolder.getStorage().get(CacheConstants.SYS_DICT_KEY + dictType);
List<SysDictData> datas = (List<SysDictData>) SaHolder.getStorage().get(GlobalConstants.SYS_DICT_KEY + dictType);
if (ObjectUtil.isNull(datas)) {
datas = SpringUtils.getAopProxy(this).selectDictDataByType(dictType);
SaHolder.getStorage().set(CacheConstants.SYS_DICT_KEY + dictType, datas);
SaHolder.getStorage().set(GlobalConstants.SYS_DICT_KEY + dictType, datas);
}
Map<String, String> map = StreamUtils.toMap(datas, SysDictData::getDictLabel, SysDictData::getDictValue);

View File

@@ -1,6 +1,7 @@
package com.ruoyi.system.service.impl;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.lang.tree.Tree;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
@@ -15,11 +16,13 @@ import com.ruoyi.component.core.util.StreamUtils;
import com.ruoyi.component.core.util.StringUtils;
import com.ruoyi.component.core.util.TreeBuildUtils;
import com.ruoyi.system.domain.SysRoleMenu;
import com.ruoyi.system.domain.SysTenantPackage;
import com.ruoyi.system.domain.vo.MetaVo;
import com.ruoyi.system.domain.vo.RouterVo;
import com.ruoyi.system.mapper.SysMenuMapper;
import com.ruoyi.system.mapper.SysRoleMapper;
import com.ruoyi.system.mapper.SysRoleMenuMapper;
import com.ruoyi.system.mapper.SysTenantPackageMapper;
import com.ruoyi.system.service.ISysMenuService;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
@@ -38,6 +41,7 @@ public class SysMenuServiceImpl implements ISysMenuService {
private final SysMenuMapper baseMapper;
private final SysRoleMapper roleMapper;
private final SysRoleMenuMapper roleMenuMapper;
private final SysTenantPackageMapper tenantPackageMapper;
/**
* 根据用户查询系统菜单列表
@@ -145,6 +149,24 @@ public class SysMenuServiceImpl implements ISysMenuService {
return baseMapper.selectMenuListByRoleId(roleId, role.getMenuCheckStrictly());
}
@Override
public List<Long> selectMenuListByPackageId(Long packageId) {
SysTenantPackage tenantPackage = tenantPackageMapper.selectById(packageId);
List<Long> menuIds = StringUtils.splitTo(tenantPackage.getMenuIds(), Convert::toLong);
if (CollUtil.isEmpty(menuIds)) {
return Collections.emptyList();
}
List<Long> parentIds = null;
if (tenantPackage.getMenuCheckStrictly()) {
parentIds = baseMapper.selectObjs(new LambdaQueryWrapper<SysMenu>()
.select(SysMenu::getParentId)
.in(SysMenu::getMenuId, menuIds));
}
return baseMapper.selectObjs(new LambdaQueryWrapper<SysMenu>()
.in(SysMenu::getMenuId, menuIds)
.notIn(CollUtil.isNotEmpty(parentIds), SysMenu::getMenuId, parentIds));
}
/**
* 构建前端路由所需要的菜单
*

View File

@@ -9,6 +9,7 @@ import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ruoyi.component.core.constant.TenantConstants;
import com.ruoyi.component.core.constant.UserConstants;
import com.ruoyi.component.mybatis.core.page.PageQuery;
import com.ruoyi.component.mybatis.core.page.TableDataInfo;
@@ -186,9 +187,10 @@ public class SysRoleServiceImpl implements ISysRoleService {
if (ObjectUtil.isNotNull(role.getRoleId()) && role.isAdmin()) {
throw new ServiceException("不允许操作超级管理员角色");
}
String[] keys = new String[]{TenantConstants.SUPER_ADMIN_ROLE_KEY, TenantConstants.TENANT_ADMIN_ROLE_KEY};
// 新增不允许使用 管理员标识符
if (ObjectUtil.isNull(role.getRoleId())
&& StringUtils.equals(role.getRoleKey(), UserConstants.ADMIN_ROLE_KEY)) {
&& StringUtils.equalsAny(role.getRoleKey(), keys)) {
throw new ServiceException("不允许使用系统内置管理员角色标识符!");
}
// 修改不允许修改 管理员标识符
@@ -196,9 +198,9 @@ public class SysRoleServiceImpl implements ISysRoleService {
SysRole sysRole = baseMapper.selectById(role.getRoleId());
// 如果标识符不相等 判断为修改了管理员标识符
if (!StringUtils.equals(sysRole.getRoleKey(), role.getRoleKey())) {
if (StringUtils.equals(sysRole.getRoleKey(), UserConstants.ADMIN_ROLE_KEY)) {
if (StringUtils.equalsAny(sysRole.getRoleKey(), keys)) {
throw new ServiceException("不允许修改系统内置管理员角色标识符!");
} else if (StringUtils.equals(role.getRoleKey(), UserConstants.ADMIN_ROLE_KEY)) {
} else if (StringUtils.equalsAny(role.getRoleKey(), keys)) {
throw new ServiceException("不允许使用系统内置管理员角色标识符!");
}
}

View File

@@ -124,7 +124,6 @@ public class SysTenantServiceImpl implements ISysTenantService {
@Transactional(rollbackFor = Exception.class)
public Boolean insertByBo(SysTenantBo bo) {
SysTenant add = BeanConvertUtil.convertTo(bo, SysTenant::new);
// 获取所有租户编号
List<String> tenantIds = baseMapper.selectObjs(
new LambdaQueryWrapper<SysTenant>().select(SysTenant::getTenantId));
@@ -187,8 +186,8 @@ public class SysTenantServiceImpl implements ISysTenantService {
dictData.setDictCode(null);
dictData.setTenantId(tenantId);
}
dictTypeMapper.insertBatch(dictTypeList);
dictDataMapper.insertBatch(dictDataList);
// dictTypeMapper.insertBatch(dictTypeList);
// dictDataMapper.insertBatch(dictDataList);
List<SysConfig> sysConfigList = configMapper.selectList(
new LambdaQueryWrapper<SysConfig>().eq(SysConfig::getTenantId, defaultTenantId));
@@ -196,7 +195,7 @@ public class SysTenantServiceImpl implements ISysTenantService {
config.setConfigId(null);
config.setTenantId(tenantId);
}
configMapper.insertBatch(sysConfigList);
// configMapper.insertBatch(sysConfigList);
return true;
}