xyz.migoo.framework.infra.service.sys.permission.MenuServiceImpl Maven / Gradle / Ivy
The newest version!
package xyz.migoo.framework.infra.service.sys.permission;
import cn.hutool.core.collection.CollUtil;
import com.google.common.annotations.VisibleForTesting;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableMultimap;
import com.google.common.collect.Lists;
import com.google.common.collect.Multimap;
import jakarta.annotation.PostConstruct;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.annotation.Lazy;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import xyz.migoo.framework.common.exception.util.ServiceExceptionUtil;
import xyz.migoo.framework.common.util.collection.CollectionUtils;
import xyz.migoo.framework.infra.controller.sys.permission.menu.vo.MenuQueryReqVO;
import xyz.migoo.framework.infra.dal.dataobject.sys.Menu;
import xyz.migoo.framework.infra.dal.mapper.sys.MenuMapper;
import xyz.migoo.framework.infra.enums.MenuIdEnum;
import xyz.migoo.framework.infra.enums.MenuTypeEnum;
import java.time.LocalDateTime;
import java.util.*;
import java.util.stream.Collectors;
import static xyz.migoo.framework.infra.enums.SysErrorCodeConstants.*;
@Service
@Slf4j
public class MenuServiceImpl implements MenuService {
/**
* 定时执行 {@link #schedulePeriodicRefresh()} 的周期
* 因为已经通过 Redis Pub/Sub 机制,所以频率不需要高
*/
private static final long SCHEDULER_PERIOD = 5 * 60 * 1000L;
/**
* 菜单缓存
* key:菜单编号
*
* 这里声明 volatile 修饰的原因是,每次刷新时,直接修改指向
*/
private volatile Map menuCache;
/**
* 权限与菜单缓存
* key:权限 {@link Menu#getPermission()}
* value:SysMenuDO 数组,因为一个权限可能对应多个 SysMenuDO 对象
*
* 这里声明 volatile 修饰的原因是,每次刷新时,直接修改指向
*/
private volatile Multimap permissionMenuCache;
/**
* 缓存菜单的最大更新时间,用于后续的增量轮询,判断是否有更新
*/
private volatile LocalDateTime maxUpdateTime;
@Resource
private MenuMapper menuMapper;
@Resource
@Lazy
private PermissionService permissionService;
/**
* 初始化 {@link #menuCache} 和 {@link #permissionMenuCache} 缓存
*/
@Override
@PostConstruct
public synchronized void initLocalCache() {
// 获取菜单列表,如果有更新
List