mirror of
http://192.168.1.205:9980/cf_devdept2/cf_imes_server.git
synced 2026-08-12 21:02:08 +08:00
权限问题修复:
1、角色权限日志提示优化; 2、修复菜单增删改清理缓存,实时生效;
This commit is contained in:
+90
-3
@@ -1,6 +1,8 @@
|
||||
package com.cf.imes.module.system.service.permission;
|
||||
|
||||
import cn.hutool.core.collection.CollUtil;
|
||||
import cn.hutool.core.collection.CollectionUtil;
|
||||
import cn.hutool.core.util.ObjectUtil;
|
||||
import com.cf.imes.framework.common.util.object.BeanUtils;
|
||||
import com.cf.imes.framework.organ.core.aop.OrganIgnore;
|
||||
import com.cf.imes.module.system.controller.admin.permission.vo.menu.MenuListReqVO;
|
||||
@@ -8,13 +10,18 @@ import com.cf.imes.module.system.controller.admin.permission.vo.menu.MenuSaveVO;
|
||||
import com.cf.imes.module.system.dal.dataobject.permission.MenuDO;
|
||||
import com.cf.imes.module.system.dal.mysql.permission.MenuMapper;
|
||||
import com.cf.imes.module.system.dal.redis.RedisKeyConstants;
|
||||
import com.cf.imes.module.system.dal.redis.RedisRefreshChannelTopicConstants;
|
||||
import com.cf.imes.module.system.enums.permission.MenuTypeEnum;
|
||||
import com.cf.imes.module.system.service.organ.OrganService;
|
||||
import com.google.common.annotations.VisibleForTesting;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.cache.annotation.CacheEvict;
|
||||
import org.springframework.cache.annotation.Cacheable;
|
||||
import org.springframework.context.annotation.Lazy;
|
||||
import org.springframework.data.redis.core.Cursor;
|
||||
import org.springframework.data.redis.core.RedisTemplate;
|
||||
import org.springframework.data.redis.core.ScanOptions;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
@@ -22,6 +29,7 @@ import javax.annotation.Resource;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
||||
import static com.cf.imes.framework.common.exception.util.ServiceExceptionUtil.exception;
|
||||
import static com.cf.imes.framework.common.util.collection.CollectionUtils.convertList;
|
||||
@@ -44,6 +52,9 @@ public class MenuServiceImpl implements MenuService {
|
||||
@Lazy // 延迟,避免循环依赖报错
|
||||
private OrganService organService;
|
||||
|
||||
@Autowired
|
||||
private RedisTemplate redisTemplate;
|
||||
|
||||
@Override
|
||||
@CacheEvict(value = RedisKeyConstants.PERMISSION_MENU_ID_LIST, key = "#createReqVO.permission",
|
||||
condition = "#createReqVO.permission != null")
|
||||
@@ -57,8 +68,13 @@ public class MenuServiceImpl implements MenuService {
|
||||
MenuDO menu = BeanUtils.toBean(createReqVO, MenuDO.class);
|
||||
initMenuProperty(menu);
|
||||
menuMapper.insert(menu);
|
||||
|
||||
Long menuId = menu.getId();
|
||||
// 清理缓存
|
||||
flushCacheWhenOperateMenu(menuId, createReqVO.getPermission(), null);
|
||||
|
||||
// 返回
|
||||
return menu.getId();
|
||||
return menuId;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -66,7 +82,8 @@ public class MenuServiceImpl implements MenuService {
|
||||
allEntries = true) // allEntries 清空所有缓存,因为 permission 如果变更,涉及到新老两个 permission。直接清理,简单有效
|
||||
public void updateMenu(MenuSaveVO updateReqVO) {
|
||||
// 校验更新的菜单是否存在
|
||||
if (menuMapper.selectById(updateReqVO.getId()) == null) {
|
||||
MenuDO menuDO = menuMapper.selectById(updateReqVO.getId());
|
||||
if (menuDO == null) {
|
||||
throw exception(MENU_NOT_EXISTS);
|
||||
}
|
||||
// 校验父菜单存在
|
||||
@@ -78,6 +95,13 @@ public class MenuServiceImpl implements MenuService {
|
||||
MenuDO updateObj = BeanUtils.toBean(updateReqVO, MenuDO.class);
|
||||
initMenuProperty(updateObj);
|
||||
menuMapper.updateById(updateObj);
|
||||
|
||||
// 权限串发生改变清空缓存
|
||||
String oldPermission = menuDO.getPermission();
|
||||
String newPermission = updateReqVO.getPermission();
|
||||
if (ObjectUtil.notEqual(oldPermission, newPermission)) {
|
||||
flushCacheWhenOperateMenu(menuDO.getId(), newPermission, oldPermission);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -90,13 +114,76 @@ public class MenuServiceImpl implements MenuService {
|
||||
throw exception(MENU_EXISTS_CHILDREN);
|
||||
}
|
||||
// 校验删除的菜单是否存在
|
||||
if (menuMapper.selectById(id) == null) {
|
||||
MenuDO menuDO = menuMapper.selectById(id);
|
||||
if (menuDO == null) {
|
||||
throw exception(MENU_NOT_EXISTS);
|
||||
}
|
||||
// 标记删除
|
||||
menuMapper.deleteById(id);
|
||||
// 删除授予给角色的权限
|
||||
permissionService.processMenuDeleted(id);
|
||||
|
||||
// 清理缓存
|
||||
flushCacheWhenOperateMenu(id, null, menuDO.getPermission());
|
||||
}
|
||||
|
||||
/**
|
||||
* 菜单增删改时清理缓存
|
||||
*
|
||||
* @param menuId 菜单id
|
||||
* @param newPermission 新权限串
|
||||
* @param oldPermission 旧权限串
|
||||
*/
|
||||
private void flushCacheWhenOperateMenu(Long menuId, String newPermission, String oldPermission) {
|
||||
CompletableFuture.runAsync(() -> {
|
||||
if (ObjectUtil.isNotNull(oldPermission)) {
|
||||
// 移除 USER_ROLE_ID_LIST:*:旧的permission
|
||||
String oldMenuPerPattern = String.format(String.valueOf(new StringBuffer(RedisKeyConstants.PERMISSION_MENU_ID_LIST).append(":*:%s")), oldPermission);
|
||||
Long oldBatchDelPerNum = scanAndDelKeys(oldMenuPerPattern);
|
||||
log.info("[updateMenu] 批量删除redis[{}]数量:{}", oldMenuPerPattern, oldBatchDelPerNum);
|
||||
}
|
||||
|
||||
if (ObjectUtil.isNotNull(newPermission)) {
|
||||
// 移除 USER_ROLE_ID_LIST:*:新的permission
|
||||
String newMenuPerPattern = String.format(String.valueOf(new StringBuffer(RedisKeyConstants.PERMISSION_MENU_ID_LIST).append(":*:%s")), newPermission);
|
||||
Long newBatchDelPerNum = scanAndDelKeys(newMenuPerPattern);
|
||||
log.info("[updateMenu] 批量删除redis[{}]数量:{}", newMenuPerPattern, newBatchDelPerNum);
|
||||
}
|
||||
|
||||
if (ObjectUtil.isNotNull(menuId)) {
|
||||
// 移除 MENU_ROLE_ID_LIST:*:menuId
|
||||
String menuRolePattern = String.format(String.valueOf(new StringBuffer(RedisKeyConstants.MENU_ROLE_ID_LIST).append(":*:%s")), menuId);
|
||||
Long batchDelRoleNum = scanAndDelKeys(menuRolePattern);
|
||||
log.info("[deleteMenu] 批量删除redis[{}]数量:{}", menuRolePattern, batchDelRoleNum);
|
||||
}
|
||||
|
||||
// 清空本地缓存
|
||||
redisTemplate.convertAndSend(RedisRefreshChannelTopicConstants.PERMISSION_REFRESH, "");
|
||||
}).exceptionally(e -> {
|
||||
log.error("[deleteMenu] redis 清空PERMISSION_MENU_ID_LIST或message发送失败, topic:{}, 异常:{}", RedisRefreshChannelTopicConstants.PERMISSION_REFRESH, e);
|
||||
return null;
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* scan所有匹配的redis key并删除
|
||||
*
|
||||
* @param keyPattern 模糊匹配的表达式
|
||||
*/
|
||||
private Long scanAndDelKeys(String keyPattern) {
|
||||
// 根据keyPattern scan匹配的redis key
|
||||
List<String> delKeys = new ArrayList<>();
|
||||
Cursor<String> cursor = redisTemplate.scan(ScanOptions.scanOptions().match(keyPattern).count(200).build());
|
||||
while (cursor.hasNext()) {
|
||||
delKeys.add(cursor.next());
|
||||
}
|
||||
cursor.close();
|
||||
// 删除匹配到的key
|
||||
if (CollectionUtil.isNotEmpty(delKeys)) {
|
||||
return redisTemplate.delete(delKeys);
|
||||
}
|
||||
return 0L;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
+4
-4
@@ -219,7 +219,7 @@ public class PermissionServiceImpl implements PermissionService {
|
||||
}
|
||||
redisTemplate.convertAndSend(RedisRefreshChannelTopicConstants.PERMISSION_REFRESH, "");
|
||||
}).exceptionally(e -> {
|
||||
log.error("[assignRoleMenu] redis message发送失败, topic:{}, 异常:{}", RedisRefreshChannelTopicConstants.PERMISSION_REFRESH, e);
|
||||
log.error("[assignRoleMenu] redis 清空MENU_ROLE_ID_LIST或message发送失败, topic:{}, 异常:{}", RedisRefreshChannelTopicConstants.PERMISSION_REFRESH, e);
|
||||
return null;
|
||||
});
|
||||
}
|
||||
@@ -240,7 +240,7 @@ public class PermissionServiceImpl implements PermissionService {
|
||||
cursor.close();
|
||||
// 删除匹配到的key
|
||||
if (CollectionUtil.isNotEmpty(delKeys)) {
|
||||
redisTemplate.delete(delKeys);
|
||||
return redisTemplate.delete(delKeys);
|
||||
}
|
||||
return 0L;
|
||||
}
|
||||
@@ -397,7 +397,7 @@ public class PermissionServiceImpl implements PermissionService {
|
||||
}
|
||||
redisTemplate.convertAndSend(RedisRefreshChannelTopicConstants.PERMISSION_REFRESH, "");
|
||||
}).exceptionally(e -> {
|
||||
log.error("[batchAssignRoleUsers] redis message发送失败, topic:{}, 异常:{}", RedisRefreshChannelTopicConstants.PERMISSION_REFRESH, e);
|
||||
log.error("[batchAssignRoleUsers] redis 清空USER_ROLE_ID_LIST或message发送失败, topic:{}, 异常:{}", RedisRefreshChannelTopicConstants.PERMISSION_REFRESH, e);
|
||||
return null;
|
||||
});
|
||||
}
|
||||
@@ -479,7 +479,7 @@ public class PermissionServiceImpl implements PermissionService {
|
||||
redisTemplate.delete(String.format(String.valueOf(new StringBuffer(RedisKeyConstants.USER_ROLE_ID_LIST).append(":%s:%s")), organId, userId));
|
||||
redisTemplate.convertAndSend(RedisRefreshChannelTopicConstants.PERMISSION_REFRESH, "");
|
||||
}).exceptionally(e -> {
|
||||
log.error("[assignUserRole] redis 清空USER_ROLE_ID_LIST或message发送失败, topic:{}, 异常:{}", RedisRefreshChannelTopicConstants.PERMISSION_REFRESH, e);
|
||||
log.error("[assignUserRole] redis message发送失败, topic:{}, 异常:{}", RedisRefreshChannelTopicConstants.PERMISSION_REFRESH, e);
|
||||
return null;
|
||||
});
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user