|
@@ -1,34 +1,25 @@
|
|
package cn.iocoder.yudao.module.system.service.permission;
|
|
package cn.iocoder.yudao.module.system.service.permission;
|
|
|
|
|
|
import cn.hutool.core.collection.CollUtil;
|
|
import cn.hutool.core.collection.CollUtil;
|
|
-import cn.hutool.core.util.StrUtil;
|
|
|
|
-import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;
|
|
|
|
import cn.iocoder.yudao.module.system.controller.admin.permission.vo.menu.MenuCreateReqVO;
|
|
import cn.iocoder.yudao.module.system.controller.admin.permission.vo.menu.MenuCreateReqVO;
|
|
import cn.iocoder.yudao.module.system.controller.admin.permission.vo.menu.MenuListReqVO;
|
|
import cn.iocoder.yudao.module.system.controller.admin.permission.vo.menu.MenuListReqVO;
|
|
import cn.iocoder.yudao.module.system.controller.admin.permission.vo.menu.MenuUpdateReqVO;
|
|
import cn.iocoder.yudao.module.system.controller.admin.permission.vo.menu.MenuUpdateReqVO;
|
|
import cn.iocoder.yudao.module.system.convert.permission.MenuConvert;
|
|
import cn.iocoder.yudao.module.system.convert.permission.MenuConvert;
|
|
import cn.iocoder.yudao.module.system.dal.dataobject.permission.MenuDO;
|
|
import cn.iocoder.yudao.module.system.dal.dataobject.permission.MenuDO;
|
|
import cn.iocoder.yudao.module.system.dal.mysql.permission.MenuMapper;
|
|
import cn.iocoder.yudao.module.system.dal.mysql.permission.MenuMapper;
|
|
|
|
+import cn.iocoder.yudao.module.system.dal.redis.RedisKeyConstants;
|
|
import cn.iocoder.yudao.module.system.enums.permission.MenuTypeEnum;
|
|
import cn.iocoder.yudao.module.system.enums.permission.MenuTypeEnum;
|
|
-import cn.iocoder.yudao.module.system.mq.producer.permission.MenuProducer;
|
|
|
|
import cn.iocoder.yudao.module.system.service.tenant.TenantService;
|
|
import cn.iocoder.yudao.module.system.service.tenant.TenantService;
|
|
import com.google.common.annotations.VisibleForTesting;
|
|
import com.google.common.annotations.VisibleForTesting;
|
|
-import com.google.common.collect.ImmutableMap;
|
|
|
|
-import com.google.common.collect.ImmutableMultimap;
|
|
|
|
-import com.google.common.collect.Multimap;
|
|
|
|
-import lombok.Getter;
|
|
|
|
-import lombok.Setter;
|
|
|
|
import lombok.extern.slf4j.Slf4j;
|
|
import lombok.extern.slf4j.Slf4j;
|
|
|
|
+import org.springframework.cache.annotation.Cacheable;
|
|
import org.springframework.context.annotation.Lazy;
|
|
import org.springframework.context.annotation.Lazy;
|
|
import org.springframework.stereotype.Service;
|
|
import org.springframework.stereotype.Service;
|
|
import org.springframework.transaction.annotation.Transactional;
|
|
import org.springframework.transaction.annotation.Transactional;
|
|
-import org.springframework.transaction.support.TransactionSynchronization;
|
|
|
|
-import org.springframework.transaction.support.TransactionSynchronizationManager;
|
|
|
|
|
|
|
|
-import javax.annotation.PostConstruct;
|
|
|
|
import javax.annotation.Resource;
|
|
import javax.annotation.Resource;
|
|
-import java.util.*;
|
|
|
|
-import java.util.stream.Collectors;
|
|
|
|
|
|
+import java.util.Collection;
|
|
|
|
+import java.util.List;
|
|
|
|
|
|
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
|
|
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
|
|
import static cn.iocoder.yudao.module.system.dal.dataobject.permission.MenuDO.ID_ROOT;
|
|
import static cn.iocoder.yudao.module.system.dal.dataobject.permission.MenuDO.ID_ROOT;
|
|
@@ -43,26 +34,6 @@ import static cn.iocoder.yudao.module.system.enums.ErrorCodeConstants.*;
|
|
@Slf4j
|
|
@Slf4j
|
|
public class MenuServiceImpl implements MenuService {
|
|
public class MenuServiceImpl implements MenuService {
|
|
|
|
|
|
- /**
|
|
|
|
- * 菜单缓存
|
|
|
|
- * key:菜单编号
|
|
|
|
- *
|
|
|
|
- * 这里声明 volatile 修饰的原因是,每次刷新时,直接修改指向
|
|
|
|
- */
|
|
|
|
- @Getter
|
|
|
|
- @Setter
|
|
|
|
- private volatile Map<Long, MenuDO> menuCache;
|
|
|
|
- /**
|
|
|
|
- * 权限与菜单缓存
|
|
|
|
- * key:权限 {@link MenuDO#getPermission()}
|
|
|
|
- * value:MenuDO 数组,因为一个权限可能对应多个 MenuDO 对象
|
|
|
|
- *
|
|
|
|
- * 这里声明 volatile 修饰的原因是,每次刷新时,直接修改指向
|
|
|
|
- */
|
|
|
|
- @Getter
|
|
|
|
- @Setter
|
|
|
|
- private volatile Multimap<String, MenuDO> permissionMenuCache;
|
|
|
|
-
|
|
|
|
@Resource
|
|
@Resource
|
|
private MenuMapper menuMapper;
|
|
private MenuMapper menuMapper;
|
|
@Resource
|
|
@Resource
|
|
@@ -71,32 +42,6 @@ public class MenuServiceImpl implements MenuService {
|
|
@Lazy // 延迟,避免循环依赖报错
|
|
@Lazy // 延迟,避免循环依赖报错
|
|
private TenantService tenantService;
|
|
private TenantService tenantService;
|
|
|
|
|
|
- @Resource
|
|
|
|
- private MenuProducer menuProducer;
|
|
|
|
-
|
|
|
|
- /**
|
|
|
|
- * 初始化 {@link #menuCache} 和 {@link #permissionMenuCache} 缓存
|
|
|
|
- */
|
|
|
|
- @Override
|
|
|
|
- @PostConstruct
|
|
|
|
- public synchronized void initLocalCache() {
|
|
|
|
- // 第一步:查询数据
|
|
|
|
- List<MenuDO> menuList = menuMapper.selectList();
|
|
|
|
- log.info("[initLocalCache][缓存菜单,数量为:{}]", menuList.size());
|
|
|
|
-
|
|
|
|
- // 第二步:构建缓存
|
|
|
|
- ImmutableMap.Builder<Long, MenuDO> menuCacheBuilder = ImmutableMap.builder();
|
|
|
|
- ImmutableMultimap.Builder<String, MenuDO> permMenuCacheBuilder = ImmutableMultimap.builder();
|
|
|
|
- menuList.forEach(menuDO -> {
|
|
|
|
- menuCacheBuilder.put(menuDO.getId(), menuDO);
|
|
|
|
- if (StrUtil.isNotEmpty(menuDO.getPermission())) { // 会存在 permission 为 null 的情况,导致 put 报 NPE 异常
|
|
|
|
- permMenuCacheBuilder.put(menuDO.getPermission(), menuDO);
|
|
|
|
- }
|
|
|
|
- });
|
|
|
|
- menuCache = menuCacheBuilder.build();
|
|
|
|
- permissionMenuCache = permMenuCacheBuilder.build();
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
@Override
|
|
@Override
|
|
public Long createMenu(MenuCreateReqVO reqVO) {
|
|
public Long createMenu(MenuCreateReqVO reqVO) {
|
|
// 校验父菜单存在
|
|
// 校验父菜单存在
|
|
@@ -108,8 +53,6 @@ public class MenuServiceImpl implements MenuService {
|
|
MenuDO menu = MenuConvert.INSTANCE.convert(reqVO);
|
|
MenuDO menu = MenuConvert.INSTANCE.convert(reqVO);
|
|
initMenuProperty(menu);
|
|
initMenuProperty(menu);
|
|
menuMapper.insert(menu);
|
|
menuMapper.insert(menu);
|
|
- // 发送刷新消息
|
|
|
|
- menuProducer.sendMenuRefreshMessage();
|
|
|
|
// 返回
|
|
// 返回
|
|
return menu.getId();
|
|
return menu.getId();
|
|
}
|
|
}
|
|
@@ -129,8 +72,6 @@ public class MenuServiceImpl implements MenuService {
|
|
MenuDO updateObject = MenuConvert.INSTANCE.convert(reqVO);
|
|
MenuDO updateObject = MenuConvert.INSTANCE.convert(reqVO);
|
|
initMenuProperty(updateObject);
|
|
initMenuProperty(updateObject);
|
|
menuMapper.updateById(updateObject);
|
|
menuMapper.updateById(updateObject);
|
|
- // 发送刷新消息
|
|
|
|
- menuProducer.sendMenuRefreshMessage();
|
|
|
|
}
|
|
}
|
|
|
|
|
|
@Override
|
|
@Override
|
|
@@ -148,15 +89,6 @@ public class MenuServiceImpl implements MenuService {
|
|
menuMapper.deleteById(menuId);
|
|
menuMapper.deleteById(menuId);
|
|
// 删除授予给角色的权限
|
|
// 删除授予给角色的权限
|
|
permissionService.processMenuDeleted(menuId);
|
|
permissionService.processMenuDeleted(menuId);
|
|
- // 发送刷新消息. 注意,需要事务提交后,在进行发送刷新消息。不然 db 还未提交,结果缓存先刷新了
|
|
|
|
- TransactionSynchronizationManager.registerSynchronization(new TransactionSynchronization() {
|
|
|
|
-
|
|
|
|
- @Override
|
|
|
|
- public void afterCommit() {
|
|
|
|
- menuProducer.sendMenuRefreshMessage();
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- });
|
|
|
|
}
|
|
}
|
|
|
|
|
|
@Override
|
|
@Override
|
|
@@ -178,33 +110,9 @@ public class MenuServiceImpl implements MenuService {
|
|
}
|
|
}
|
|
|
|
|
|
@Override
|
|
@Override
|
|
- public List<MenuDO> getMenuListFromCache(Collection<Integer> menuTypes, Collection<Integer> menusStatuses) {
|
|
|
|
- // 任一一个参数为空,则返回空
|
|
|
|
- if (CollectionUtils.isAnyEmpty(menuTypes, menusStatuses)) {
|
|
|
|
- return Collections.emptyList();
|
|
|
|
- }
|
|
|
|
- // 创建新数组,避免缓存被修改
|
|
|
|
- return menuCache.values().stream().filter(menu -> menuTypes.contains(menu.getType())
|
|
|
|
- && menusStatuses.contains(menu.getStatus()))
|
|
|
|
- .collect(Collectors.toList());
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- @Override
|
|
|
|
- public List<MenuDO> getMenuListFromCache(Collection<Long> menuIds, Collection<Integer> menuTypes,
|
|
|
|
- Collection<Integer> menusStatuses) {
|
|
|
|
- // 任一一个参数为空,则返回空
|
|
|
|
- if (CollectionUtils.isAnyEmpty(menuIds, menuTypes, menusStatuses)) {
|
|
|
|
- return Collections.emptyList();
|
|
|
|
- }
|
|
|
|
- return menuCache.values().stream().filter(menu -> menuIds.contains(menu.getId())
|
|
|
|
- && menuTypes.contains(menu.getType())
|
|
|
|
- && menusStatuses.contains(menu.getStatus()))
|
|
|
|
- .collect(Collectors.toList());
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- @Override
|
|
|
|
|
|
+ @Cacheable(value = RedisKeyConstants.PERMISSION_MENU_ID_LIST, key = "#permission")
|
|
public List<MenuDO> getMenuListByPermissionFromCache(String permission) {
|
|
public List<MenuDO> getMenuListByPermissionFromCache(String permission) {
|
|
- return new ArrayList<>(permissionMenuCache.get(permission));
|
|
|
|
|
|
+ return menuMapper.selectListByPermission(permission);
|
|
}
|
|
}
|
|
|
|
|
|
@Override
|
|
@Override
|