mirror of
https://github.com/continew-org/continew-admin.git
synced 2025-09-09 20:57:21 +08:00
fix(system/role): 修复角色菜单权限缓存未清理错误,优化角色菜单缓存逻辑
Closes #IBNENK
This commit is contained in:
@@ -42,9 +42,9 @@ public class CacheConstants {
|
||||
public static final String USER_KEY_PREFIX = "USER" + DELIMITER;
|
||||
|
||||
/**
|
||||
* 菜单缓存键前缀
|
||||
* 角色菜单缓存键前缀
|
||||
*/
|
||||
public static final String MENU_KEY_PREFIX = "MENU" + DELIMITER;
|
||||
public static final String ROLE_MENU_KEY_PREFIX = "ROLE_MENU" + DELIMITER;
|
||||
|
||||
/**
|
||||
* 字典缓存键前缀
|
||||
|
@@ -17,6 +17,7 @@
|
||||
package top.continew.admin.common.context;
|
||||
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
import top.continew.admin.common.enums.DataScopeEnum;
|
||||
|
||||
import java.io.Serial;
|
||||
@@ -29,6 +30,7 @@ import java.io.Serializable;
|
||||
* @since 2023/3/7 22:08
|
||||
*/
|
||||
@Data
|
||||
@NoArgsConstructor
|
||||
public class RoleContext implements Serializable {
|
||||
|
||||
@Serial
|
||||
@@ -48,4 +50,10 @@ public class RoleContext implements Serializable {
|
||||
* 数据权限
|
||||
*/
|
||||
private DataScopeEnum dataScope;
|
||||
|
||||
public RoleContext(Long id, String code, DataScopeEnum dataScope) {
|
||||
this.id = id;
|
||||
this.code = code;
|
||||
this.dataScope = dataScope;
|
||||
}
|
||||
}
|
||||
|
@@ -32,6 +32,7 @@ import top.continew.admin.auth.model.resp.LoginResp;
|
||||
import top.continew.admin.auth.model.resp.RouteResp;
|
||||
import top.continew.admin.auth.service.AuthService;
|
||||
import top.continew.admin.common.constant.SysConstants;
|
||||
import top.continew.admin.common.context.RoleContext;
|
||||
import top.continew.admin.common.enums.DisEnableStatusEnum;
|
||||
import top.continew.admin.system.enums.MenuTypeEnum;
|
||||
import top.continew.admin.system.model.resp.ClientResp;
|
||||
@@ -86,16 +87,16 @@ public class AuthServiceImpl implements AuthService {
|
||||
|
||||
@Override
|
||||
public List<RouteResp> buildRouteTree(Long userId) {
|
||||
Set<String> roleCodeSet = roleService.listCodeByUserId(userId);
|
||||
if (CollUtil.isEmpty(roleCodeSet)) {
|
||||
Set<RoleContext> roleSet = roleService.listByUserId(userId);
|
||||
if (CollUtil.isEmpty(roleSet)) {
|
||||
return new ArrayList<>(0);
|
||||
}
|
||||
// 查询菜单列表
|
||||
Set<MenuResp> menuSet = new LinkedHashSet<>();
|
||||
if (roleCodeSet.contains(SysConstants.SUPER_ROLE_CODE)) {
|
||||
menuSet.addAll(menuService.listAll());
|
||||
if (roleSet.stream().anyMatch(r -> SysConstants.SUPER_ROLE_ID.equals(r.getId()))) {
|
||||
menuSet.addAll(menuService.listByRoleId(SysConstants.SUPER_ROLE_ID));
|
||||
} else {
|
||||
roleCodeSet.forEach(roleCode -> menuSet.addAll(menuService.listByRoleCode(roleCode)));
|
||||
roleSet.forEach(r -> menuSet.addAll(menuService.listByRoleId(r.getId())));
|
||||
}
|
||||
List<MenuResp> menuList = menuSet.stream().filter(m -> !MenuTypeEnum.BUTTON.equals(m.getType())).toList();
|
||||
if (CollUtil.isEmpty(menuList)) {
|
||||
|
@@ -40,10 +40,10 @@ public interface MenuMapper extends BaseMapper<MenuDO> {
|
||||
Set<String> selectPermissionByUserId(@Param("userId") Long userId);
|
||||
|
||||
/**
|
||||
* 根据角色编码查询
|
||||
* 根据角色 ID 查询
|
||||
*
|
||||
* @param roleCode 角色编码
|
||||
* @param roleId 角色 ID
|
||||
* @return 菜单列表
|
||||
*/
|
||||
List<MenuDO> selectListByRoleCode(@Param("roleCode") String roleCode);
|
||||
List<MenuDO> selectListByRoleId(@Param("roleId") Long roleId);
|
||||
}
|
||||
|
@@ -34,13 +34,6 @@ import java.util.Set;
|
||||
*/
|
||||
public interface MenuService extends BaseService<MenuResp, MenuResp, MenuQuery, MenuReq>, IService<MenuDO> {
|
||||
|
||||
/**
|
||||
* 查询全部菜单
|
||||
*
|
||||
* @return 菜单列表
|
||||
*/
|
||||
List<MenuResp> listAll();
|
||||
|
||||
/**
|
||||
* 根据用户 ID 查询
|
||||
*
|
||||
@@ -50,10 +43,10 @@ public interface MenuService extends BaseService<MenuResp, MenuResp, MenuQuery,
|
||||
Set<String> listPermissionByUserId(Long userId);
|
||||
|
||||
/**
|
||||
* 根据角色编码查询
|
||||
* 根据角色 ID 查询
|
||||
*
|
||||
* @param roleCode 角色编码
|
||||
* @param roleId 角色 ID
|
||||
* @return 菜单列表
|
||||
*/
|
||||
List<MenuResp> listByRoleCode(String roleCode);
|
||||
List<MenuResp> listByRoleId(Long roleId);
|
||||
}
|
||||
|
@@ -23,6 +23,7 @@ import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
import top.continew.admin.common.constant.CacheConstants;
|
||||
import top.continew.admin.common.constant.SysConstants;
|
||||
import top.continew.admin.common.enums.DisEnableStatusEnum;
|
||||
import top.continew.admin.system.enums.MenuTypeEnum;
|
||||
import top.continew.admin.system.mapper.MenuMapper;
|
||||
@@ -62,7 +63,7 @@ public class MenuServiceImpl extends BaseServiceImpl<MenuMapper, MenuDO, MenuRes
|
||||
if (MenuTypeEnum.DIR.equals(req.getType())) {
|
||||
req.setComponent(StrUtil.blankToDefault(req.getComponent(), "Layout"));
|
||||
}
|
||||
RedisUtils.deleteByPattern(CacheConstants.MENU_KEY_PREFIX + StringConstants.ASTERISK);
|
||||
RedisUtils.deleteByPattern(CacheConstants.ROLE_MENU_KEY_PREFIX + StringConstants.ASTERISK);
|
||||
return super.add(req);
|
||||
}
|
||||
|
||||
@@ -78,7 +79,7 @@ public class MenuServiceImpl extends BaseServiceImpl<MenuMapper, MenuDO, MenuRes
|
||||
MenuDO oldMenu = super.getById(id);
|
||||
CheckUtils.throwIfNotEqual(req.getType(), oldMenu.getType(), "不允许修改菜单类型");
|
||||
super.update(req, id);
|
||||
RedisUtils.deleteByPattern(CacheConstants.MENU_KEY_PREFIX + StringConstants.ASTERISK);
|
||||
RedisUtils.deleteByPattern(CacheConstants.ROLE_MENU_KEY_PREFIX + StringConstants.ASTERISK);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -86,13 +87,7 @@ public class MenuServiceImpl extends BaseServiceImpl<MenuMapper, MenuDO, MenuRes
|
||||
public void delete(List<Long> ids) {
|
||||
baseMapper.lambdaUpdate().in(MenuDO::getParentId, ids).remove();
|
||||
super.delete(ids);
|
||||
RedisUtils.deleteByPattern(CacheConstants.MENU_KEY_PREFIX + StringConstants.ASTERISK);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Cached(key = "'ALL'", name = CacheConstants.MENU_KEY_PREFIX)
|
||||
public List<MenuResp> listAll() {
|
||||
return super.list(new MenuQuery(DisEnableStatusEnum.ENABLE), null);
|
||||
RedisUtils.deleteByPattern(CacheConstants.ROLE_MENU_KEY_PREFIX + StringConstants.ASTERISK);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -101,9 +96,12 @@ public class MenuServiceImpl extends BaseServiceImpl<MenuMapper, MenuDO, MenuRes
|
||||
}
|
||||
|
||||
@Override
|
||||
@Cached(key = "#roleCode", name = CacheConstants.MENU_KEY_PREFIX)
|
||||
public List<MenuResp> listByRoleCode(String roleCode) {
|
||||
List<MenuDO> menuList = baseMapper.selectListByRoleCode(roleCode);
|
||||
@Cached(key = "#roleId", name = CacheConstants.ROLE_MENU_KEY_PREFIX)
|
||||
public List<MenuResp> listByRoleId(Long roleId) {
|
||||
if (SysConstants.SUPER_ROLE_ID.equals(roleId)) {
|
||||
return super.list(new MenuQuery(DisEnableStatusEnum.ENABLE), null);
|
||||
}
|
||||
List<MenuDO> menuList = baseMapper.selectListByRoleId(roleId);
|
||||
List<MenuResp> list = BeanUtil.copyToList(menuList, MenuResp.class);
|
||||
list.forEach(super::fill);
|
||||
return list;
|
||||
|
@@ -18,7 +18,6 @@ package top.continew.admin.system.service.impl;
|
||||
|
||||
import cn.crane4j.annotation.ContainerMethod;
|
||||
import cn.crane4j.annotation.MappingType;
|
||||
import cn.hutool.core.bean.BeanUtil;
|
||||
import cn.hutool.core.collection.CollUtil;
|
||||
import cn.hutool.core.util.ObjectUtil;
|
||||
import com.alicp.jetcache.anno.CacheInvalidate;
|
||||
@@ -45,7 +44,10 @@ import top.continew.admin.system.service.*;
|
||||
import top.continew.starter.core.validation.CheckUtils;
|
||||
import top.continew.starter.extension.crud.service.BaseServiceImpl;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
@@ -79,7 +81,6 @@ public class RoleServiceImpl extends BaseServiceImpl<RoleMapper, RoleDO, RoleRes
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
@CacheInvalidate(key = "#req.code == 'admin' ? 'ALL' : #req.code", name = CacheConstants.MENU_KEY_PREFIX)
|
||||
public void update(RoleReq req, Long id) {
|
||||
String name = req.getName();
|
||||
CheckUtils.throwIf(this.isNameExists(name, id), "修改失败,[{}] 已存在", name);
|
||||
@@ -120,6 +121,7 @@ public class RoleServiceImpl extends BaseServiceImpl<RoleMapper, RoleDO, RoleRes
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
@CacheInvalidate(key = "#id", name = CacheConstants.ROLE_MENU_KEY_PREFIX)
|
||||
public void updatePermission(Long id, RoleUpdatePermissionReq req) {
|
||||
super.getById(id);
|
||||
// 保存角色和菜单关联
|
||||
@@ -148,13 +150,9 @@ public class RoleServiceImpl extends BaseServiceImpl<RoleMapper, RoleDO, RoleRes
|
||||
super.fill(obj);
|
||||
if (obj instanceof RoleDetailResp detail) {
|
||||
Long roleId = detail.getId();
|
||||
if (SysConstants.SUPER_ROLE_CODE.equals(detail.getCode())) {
|
||||
List<MenuResp> list = menuService.listAll();
|
||||
List<Long> menuIds = list.stream().map(MenuResp::getId).toList();
|
||||
detail.setMenuIds(menuIds);
|
||||
} else {
|
||||
detail.setMenuIds(roleMenuService.listMenuIdByRoleIds(CollUtil.newArrayList(roleId)));
|
||||
}
|
||||
List<MenuResp> list = menuService.listByRoleId(roleId);
|
||||
List<Long> menuIds = list.stream().map(MenuResp::getId).toList();
|
||||
detail.setMenuIds(menuIds);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -194,8 +192,13 @@ public class RoleServiceImpl extends BaseServiceImpl<RoleMapper, RoleDO, RoleRes
|
||||
if (CollUtil.isEmpty(roleIdList)) {
|
||||
return Collections.emptySet();
|
||||
}
|
||||
List<RoleDO> roleList = baseMapper.lambdaQuery().in(RoleDO::getId, roleIdList).list();
|
||||
return new HashSet<>(BeanUtil.copyToList(roleList, RoleContext.class));
|
||||
List<RoleDO> roleList = baseMapper.lambdaQuery()
|
||||
.select(RoleDO::getId, RoleDO::getCode, RoleDO::getDataScope)
|
||||
.in(RoleDO::getId, roleIdList)
|
||||
.list();
|
||||
return roleList.stream()
|
||||
.map(r -> new RoleContext(r.getId(), r.getCode(), r.getDataScope()))
|
||||
.collect(Collectors.toSet());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@@ -13,12 +13,12 @@
|
||||
AND t1.permission IS NOT NULL
|
||||
</select>
|
||||
|
||||
<select id="selectListByRoleCode" resultType="top.continew.admin.system.model.entity.MenuDO">
|
||||
<select id="selectListByRoleId" resultType="top.continew.admin.system.model.entity.MenuDO">
|
||||
SELECT t1.*
|
||||
FROM sys_menu AS t1
|
||||
LEFT JOIN sys_role_menu AS t2 ON t2.menu_id = t1.id
|
||||
LEFT JOIN sys_role AS t3 ON t3.id = t2.role_id
|
||||
WHERE t3.code = #{roleCode}
|
||||
WHERE t3.id = #{roleId}
|
||||
AND t1.status = 1
|
||||
</select>
|
||||
</mapper>
|
@@ -131,7 +131,7 @@ public class DemoEnvironmentJob {
|
||||
roleMenuMapper.lambdaUpdate().notIn(RoleMenuDO::getRoleId, ROLE_FLAG).remove();
|
||||
return roleMapper.lambdaUpdate().notIn(RoleDO::getId, ROLE_FLAG).remove();
|
||||
});
|
||||
this.clean(menuCount, "菜单", CacheConstants.MENU_KEY_PREFIX, () -> menuMapper.lambdaUpdate()
|
||||
this.clean(menuCount, "菜单", CacheConstants.ROLE_MENU_KEY_PREFIX, () -> menuMapper.lambdaUpdate()
|
||||
.gt(MenuDO::getId, DELETE_FLAG)
|
||||
.remove());
|
||||
this.clean(deptCount, "部门", null, () -> deptMapper.lambdaUpdate().gt(DeptDO::getId, DEPT_FLAG).remove());
|
||||
|
Reference in New Issue
Block a user