perf: 对获取路由信息接口增加缓存处理
1.优化 Spring Cache 配置 2.暂时移除 Jackson 针对数值类型:Long、BigInteger、BigDecimal 的 toString 处理(TreeUtil 疑似在字符串类型 parentId 时会出现转换异常)
This commit is contained in:
parent
d7c0dce608
commit
4639d13ba6
@ -0,0 +1,102 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2022-present Charles7c Authors. All Rights Reserved.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package top.charles7c.cnadmin.common.config;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import lombok.RequiredArgsConstructor;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
|
||||||
|
import org.redisson.codec.JsonJacksonCodec;
|
||||||
|
import org.redisson.spring.starter.RedissonAutoConfigurationCustomizer;
|
||||||
|
import org.springframework.boot.autoconfigure.cache.CacheProperties;
|
||||||
|
import org.springframework.cache.annotation.CachingConfigurerSupport;
|
||||||
|
import org.springframework.cache.annotation.EnableCaching;
|
||||||
|
import org.springframework.cache.interceptor.KeyGenerator;
|
||||||
|
import org.springframework.context.annotation.Bean;
|
||||||
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
import org.springframework.data.redis.cache.RedisCacheConfiguration;
|
||||||
|
import org.springframework.data.redis.serializer.*;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.annotation.JsonTypeInfo;
|
||||||
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||||
|
|
||||||
|
import cn.hutool.core.map.MapUtil;
|
||||||
|
import cn.hutool.core.util.StrUtil;
|
||||||
|
import cn.hutool.crypto.digest.DigestUtil;
|
||||||
|
import cn.hutool.json.JSONUtil;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Redis 配置
|
||||||
|
*
|
||||||
|
* @author Charles7c
|
||||||
|
* @since 2022/12/28 23:17
|
||||||
|
*/
|
||||||
|
@Slf4j
|
||||||
|
@EnableCaching
|
||||||
|
@Configuration
|
||||||
|
@RequiredArgsConstructor
|
||||||
|
public class RedisConfiguration extends CachingConfigurerSupport {
|
||||||
|
|
||||||
|
private final ObjectMapper objectMapper;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Redisson 自定义配置
|
||||||
|
*/
|
||||||
|
@Bean
|
||||||
|
public RedissonAutoConfigurationCustomizer redissonCustomizer() {
|
||||||
|
// 解决序列化乱码问题
|
||||||
|
return config -> config.setCodec(new JsonJacksonCodec(objectMapper));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 解决 Spring Cache(@Cacheable)缓存乱码问题
|
||||||
|
*/
|
||||||
|
@Bean
|
||||||
|
public RedisCacheConfiguration redisCacheConfiguration(CacheProperties cacheProperties) {
|
||||||
|
ObjectMapper objectMapperCopy =
|
||||||
|
objectMapper.copy().enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL, JsonTypeInfo.As.PROPERTY);
|
||||||
|
RedisCacheConfiguration redisCacheConfiguration = RedisCacheConfiguration.defaultCacheConfig()
|
||||||
|
.serializeKeysWith(RedisSerializationContext.SerializationPair.fromSerializer(new StringRedisSerializer()))
|
||||||
|
.serializeValuesWith(RedisSerializationContext.SerializationPair
|
||||||
|
.fromSerializer(new GenericJackson2JsonRedisSerializer(objectMapperCopy)));
|
||||||
|
CacheProperties.Redis redisCacheProperties = cacheProperties.getRedis();
|
||||||
|
if (null != redisCacheProperties.getTimeToLive()) {
|
||||||
|
redisCacheConfiguration = redisCacheConfiguration.entryTtl(redisCacheProperties.getTimeToLive());
|
||||||
|
}
|
||||||
|
if (!redisCacheProperties.isCacheNullValues()) {
|
||||||
|
redisCacheConfiguration = redisCacheConfiguration.disableCachingNullValues();
|
||||||
|
}
|
||||||
|
return redisCacheConfiguration;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 自定义缓存 key 生成策略(如果 @Cacheable 不指定 key,则默认使用该策略)
|
||||||
|
*/
|
||||||
|
@Bean
|
||||||
|
@Override
|
||||||
|
public KeyGenerator keyGenerator() {
|
||||||
|
return (target, method, params) -> {
|
||||||
|
String key = StrUtil.toUnderlineCase(method.getName()).toUpperCase();
|
||||||
|
Map<String, Object> paramMap = MapUtil.newHashMap(params.length);
|
||||||
|
for (int i = 0; i < params.length; i++) {
|
||||||
|
paramMap.put(String.valueOf(i), params[i]);
|
||||||
|
}
|
||||||
|
return String.format("%s:%s", key, DigestUtil.sha256Hex(JSONUtil.toJsonStr(paramMap)));
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
@ -1,52 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2022-present Charles7c Authors. All Rights Reserved.
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package top.charles7c.cnadmin.common.config;
|
|
||||||
|
|
||||||
import lombok.RequiredArgsConstructor;
|
|
||||||
import lombok.extern.slf4j.Slf4j;
|
|
||||||
|
|
||||||
import org.redisson.codec.JsonJacksonCodec;
|
|
||||||
import org.redisson.spring.starter.RedissonAutoConfigurationCustomizer;
|
|
||||||
import org.springframework.cache.annotation.EnableCaching;
|
|
||||||
import org.springframework.context.annotation.Bean;
|
|
||||||
import org.springframework.context.annotation.Configuration;
|
|
||||||
|
|
||||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Redisson 配置
|
|
||||||
*
|
|
||||||
* @author Charles7c
|
|
||||||
* @since 2022/12/28 23:17
|
|
||||||
*/
|
|
||||||
@Slf4j
|
|
||||||
@EnableCaching
|
|
||||||
@Configuration
|
|
||||||
@RequiredArgsConstructor
|
|
||||||
public class RedissonConfiguration {
|
|
||||||
|
|
||||||
private final ObjectMapper objectMapper;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Redisson 自定义配置
|
|
||||||
*/
|
|
||||||
@Bean
|
|
||||||
public RedissonAutoConfigurationCustomizer redissonCustomizer() {
|
|
||||||
// 解决序列化乱码问题
|
|
||||||
return config -> config.setCodec(new JsonJacksonCodec(objectMapper));
|
|
||||||
}
|
|
||||||
}
|
|
@ -16,8 +16,6 @@
|
|||||||
|
|
||||||
package top.charles7c.cnadmin.common.config.jackson;
|
package top.charles7c.cnadmin.common.config.jackson;
|
||||||
|
|
||||||
import java.math.BigDecimal;
|
|
||||||
import java.math.BigInteger;
|
|
||||||
import java.time.LocalDate;
|
import java.time.LocalDate;
|
||||||
import java.time.LocalDateTime;
|
import java.time.LocalDateTime;
|
||||||
import java.time.LocalTime;
|
import java.time.LocalTime;
|
||||||
@ -33,7 +31,6 @@ import org.springframework.http.converter.json.Jackson2ObjectMapperBuilder;
|
|||||||
|
|
||||||
import com.fasterxml.jackson.databind.*;
|
import com.fasterxml.jackson.databind.*;
|
||||||
import com.fasterxml.jackson.databind.module.SimpleModule;
|
import com.fasterxml.jackson.databind.module.SimpleModule;
|
||||||
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
|
|
||||||
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
|
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
|
||||||
import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateDeserializer;
|
import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateDeserializer;
|
||||||
import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateTimeDeserializer;
|
import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateTimeDeserializer;
|
||||||
@ -57,19 +54,12 @@ import top.charles7c.cnadmin.common.base.BaseEnum;
|
|||||||
public class JacksonConfiguration {
|
public class JacksonConfiguration {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 针对数值类型:Long、BigInteger、BigDecimal,时间类型:LocalDateTime、LocalDate、LocalTime 的序列化和反序列化
|
* 针对时间类型:LocalDateTime、LocalDate、LocalTime 的序列化和反序列化
|
||||||
*/
|
*/
|
||||||
@Bean
|
@Bean
|
||||||
public Jackson2ObjectMapperBuilderCustomizer customizer() {
|
public Jackson2ObjectMapperBuilderCustomizer customizer() {
|
||||||
return builder -> {
|
return builder -> {
|
||||||
JavaTimeModule javaTimeModule = new JavaTimeModule();
|
JavaTimeModule javaTimeModule = new JavaTimeModule();
|
||||||
// 针对数值类型:Long、BigInteger、BigDecimal 的序列化
|
|
||||||
javaTimeModule.addSerializer(Long.class, ToStringSerializer.instance);
|
|
||||||
javaTimeModule.addSerializer(Long.TYPE, ToStringSerializer.instance);
|
|
||||||
javaTimeModule.addSerializer(BigInteger.class, ToStringSerializer.instance);
|
|
||||||
javaTimeModule.addSerializer(BigDecimal.class, ToStringSerializer.instance);
|
|
||||||
|
|
||||||
// 针对时间类型:LocalDateTime、LocalDate、LocalTime 的序列化和反序列化
|
|
||||||
DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern(DatePattern.NORM_DATETIME_PATTERN);
|
DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern(DatePattern.NORM_DATETIME_PATTERN);
|
||||||
javaTimeModule.addSerializer(LocalDateTime.class, new LocalDateTimeSerializer(dateTimeFormatter));
|
javaTimeModule.addSerializer(LocalDateTime.class, new LocalDateTimeSerializer(dateTimeFormatter));
|
||||||
javaTimeModule.addDeserializer(LocalDateTime.class, new LocalDateTimeDeserializer(dateTimeFormatter));
|
javaTimeModule.addDeserializer(LocalDateTime.class, new LocalDateTimeDeserializer(dateTimeFormatter));
|
||||||
|
@ -47,4 +47,9 @@ public class CacheConsts {
|
|||||||
* 用户缓存键前缀
|
* 用户缓存键前缀
|
||||||
*/
|
*/
|
||||||
public static final String USER_KEY_PREFIX = "USER";
|
public static final String USER_KEY_PREFIX = "USER";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 菜单缓存键前缀
|
||||||
|
*/
|
||||||
|
public static final String MENU_KEY_PREFIX = "MENU";
|
||||||
}
|
}
|
||||||
|
@ -16,9 +16,8 @@
|
|||||||
|
|
||||||
package top.charles7c.cnadmin.auth.service.impl;
|
package top.charles7c.cnadmin.auth.service.impl;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.*;
|
||||||
import java.util.List;
|
import java.util.stream.Collectors;
|
||||||
import java.util.Set;
|
|
||||||
|
|
||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
|
|
||||||
@ -44,7 +43,6 @@ import top.charles7c.cnadmin.common.util.TreeUtils;
|
|||||||
import top.charles7c.cnadmin.common.util.helper.LoginHelper;
|
import top.charles7c.cnadmin.common.util.helper.LoginHelper;
|
||||||
import top.charles7c.cnadmin.common.util.validate.CheckUtils;
|
import top.charles7c.cnadmin.common.util.validate.CheckUtils;
|
||||||
import top.charles7c.cnadmin.system.model.entity.UserDO;
|
import top.charles7c.cnadmin.system.model.entity.UserDO;
|
||||||
import top.charles7c.cnadmin.system.model.query.MenuQuery;
|
|
||||||
import top.charles7c.cnadmin.system.model.vo.DeptDetailVO;
|
import top.charles7c.cnadmin.system.model.vo.DeptDetailVO;
|
||||||
import top.charles7c.cnadmin.system.model.vo.MenuVO;
|
import top.charles7c.cnadmin.system.model.vo.MenuVO;
|
||||||
import top.charles7c.cnadmin.system.service.DeptService;
|
import top.charles7c.cnadmin.system.service.DeptService;
|
||||||
@ -91,21 +89,20 @@ public class LoginServiceImpl implements LoginService {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<RouteVO> buildRouteTree(Long userId) {
|
public List<RouteVO> buildRouteTree(Long userId) {
|
||||||
Set<String> roleSet = permissionService.listRoleCodeByUserId(userId);
|
Set<String> roleCodeSet = permissionService.listRoleCodeByUserId(userId);
|
||||||
if (CollUtil.isEmpty(roleSet)) {
|
if (CollUtil.isEmpty(roleCodeSet)) {
|
||||||
return new ArrayList<>(0);
|
return new ArrayList<>(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 查询菜单列表
|
// 查询菜单列表
|
||||||
List<MenuVO> menuList;
|
Set<MenuVO> menuSet = new LinkedHashSet<>();
|
||||||
if (roleSet.contains(SysConsts.ADMIN_ROLE_CODE)) {
|
if (roleCodeSet.contains(SysConsts.ADMIN_ROLE_CODE)) {
|
||||||
MenuQuery menuQuery = new MenuQuery();
|
menuSet.addAll(menuService.list());
|
||||||
menuQuery.setStatus(DisEnableStatusEnum.ENABLE.getValue());
|
|
||||||
menuList = menuService.list(menuQuery, null);
|
|
||||||
} else {
|
} else {
|
||||||
menuList = menuService.listByUserId(userId);
|
roleCodeSet.forEach(roleCode -> menuSet.addAll(menuService.listByRoleCode(roleCode)));
|
||||||
}
|
}
|
||||||
menuList.removeIf(m -> MenuTypeEnum.BUTTON.equals(m.getType()));
|
List<MenuVO> menuList =
|
||||||
|
menuSet.stream().filter(m -> !MenuTypeEnum.BUTTON.equals(m.getType())).collect(Collectors.toList());
|
||||||
|
|
||||||
// 构建路由树
|
// 构建路由树
|
||||||
TreeField treeField = MenuVO.class.getDeclaredAnnotation(TreeField.class);
|
TreeField treeField = MenuVO.class.getDeclaredAnnotation(TreeField.class);
|
||||||
|
@ -42,11 +42,11 @@ public interface MenuMapper extends BaseMapper<MenuDO> {
|
|||||||
Set<String> selectPermissionByUserId(@Param("userId") Long userId);
|
Set<String> selectPermissionByUserId(@Param("userId") Long userId);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 根据用户 ID 查询
|
* 根据角色编码查询
|
||||||
*
|
*
|
||||||
* @param userId
|
* @param roleCode
|
||||||
* 用户 ID
|
* 角色编码
|
||||||
* @return 菜单列表
|
* @return 菜单列表
|
||||||
*/
|
*/
|
||||||
List<MenuDO> selectListByUserId(@Param("userId") Long userId);
|
List<MenuDO> selectListByRoleCode(@Param("roleCode") String roleCode);
|
||||||
}
|
}
|
||||||
|
@ -42,11 +42,18 @@ public interface MenuService extends BaseService<MenuVO, MenuVO, MenuQuery, Menu
|
|||||||
Set<String> listPermissionByUserId(Long userId);
|
Set<String> listPermissionByUserId(Long userId);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 根据用户 ID 查询
|
* 根据角色编码查询
|
||||||
*
|
*
|
||||||
* @param userId
|
* @param roleCode
|
||||||
* 用户 ID
|
* 角色编码
|
||||||
* @return 菜单列表
|
* @return 菜单列表
|
||||||
*/
|
*/
|
||||||
List<MenuVO> listByUserId(Long userId);
|
List<MenuVO> listByRoleCode(String roleCode);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 查询所有菜单
|
||||||
|
*
|
||||||
|
* @return 菜单列表
|
||||||
|
*/
|
||||||
|
List<MenuVO> list();
|
||||||
}
|
}
|
||||||
|
@ -20,12 +20,16 @@ import java.util.*;
|
|||||||
|
|
||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
|
|
||||||
|
import org.springframework.cache.annotation.CacheConfig;
|
||||||
|
import org.springframework.cache.annotation.CacheEvict;
|
||||||
|
import org.springframework.cache.annotation.Cacheable;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
import org.springframework.transaction.annotation.Transactional;
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
|
|
||||||
import cn.hutool.core.bean.BeanUtil;
|
import cn.hutool.core.bean.BeanUtil;
|
||||||
|
|
||||||
import top.charles7c.cnadmin.common.base.BaseServiceImpl;
|
import top.charles7c.cnadmin.common.base.BaseServiceImpl;
|
||||||
|
import top.charles7c.cnadmin.common.constant.CacheConsts;
|
||||||
import top.charles7c.cnadmin.common.enums.DisEnableStatusEnum;
|
import top.charles7c.cnadmin.common.enums.DisEnableStatusEnum;
|
||||||
import top.charles7c.cnadmin.common.util.validate.CheckUtils;
|
import top.charles7c.cnadmin.common.util.validate.CheckUtils;
|
||||||
import top.charles7c.cnadmin.system.mapper.MenuMapper;
|
import top.charles7c.cnadmin.system.mapper.MenuMapper;
|
||||||
@ -43,10 +47,12 @@ import top.charles7c.cnadmin.system.service.MenuService;
|
|||||||
*/
|
*/
|
||||||
@Service
|
@Service
|
||||||
@RequiredArgsConstructor
|
@RequiredArgsConstructor
|
||||||
|
@CacheConfig(cacheNames = CacheConsts.MENU_KEY_PREFIX)
|
||||||
public class MenuServiceImpl extends BaseServiceImpl<MenuMapper, MenuDO, MenuVO, MenuVO, MenuQuery, MenuRequest>
|
public class MenuServiceImpl extends BaseServiceImpl<MenuMapper, MenuDO, MenuVO, MenuVO, MenuQuery, MenuRequest>
|
||||||
implements MenuService {
|
implements MenuService {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@CacheEvict(allEntries = true)
|
||||||
@Transactional(rollbackFor = Exception.class)
|
@Transactional(rollbackFor = Exception.class)
|
||||||
public Long add(MenuRequest request) {
|
public Long add(MenuRequest request) {
|
||||||
String title = request.getTitle();
|
String title = request.getTitle();
|
||||||
@ -58,6 +64,7 @@ public class MenuServiceImpl extends BaseServiceImpl<MenuMapper, MenuDO, MenuVO,
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@CacheEvict(allEntries = true)
|
||||||
@Transactional(rollbackFor = Exception.class)
|
@Transactional(rollbackFor = Exception.class)
|
||||||
public void update(MenuRequest request, Long id) {
|
public void update(MenuRequest request, Long id) {
|
||||||
String title = request.getTitle();
|
String title = request.getTitle();
|
||||||
@ -68,6 +75,7 @@ public class MenuServiceImpl extends BaseServiceImpl<MenuMapper, MenuDO, MenuVO,
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@CacheEvict(allEntries = true)
|
||||||
@Transactional(rollbackFor = Exception.class)
|
@Transactional(rollbackFor = Exception.class)
|
||||||
public void delete(List<Long> ids) {
|
public void delete(List<Long> ids) {
|
||||||
baseMapper.lambdaUpdate().in(MenuDO::getParentId, ids).remove();
|
baseMapper.lambdaUpdate().in(MenuDO::getParentId, ids).remove();
|
||||||
@ -80,13 +88,22 @@ public class MenuServiceImpl extends BaseServiceImpl<MenuMapper, MenuDO, MenuVO,
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<MenuVO> listByUserId(Long userId) {
|
@Cacheable(key = "#roleCode")
|
||||||
List<MenuDO> menuList = baseMapper.selectListByUserId(userId);
|
public List<MenuVO> listByRoleCode(String roleCode) {
|
||||||
|
List<MenuDO> menuList = baseMapper.selectListByRoleCode(roleCode);
|
||||||
List<MenuVO> list = BeanUtil.copyToList(menuList, MenuVO.class);
|
List<MenuVO> list = BeanUtil.copyToList(menuList, MenuVO.class);
|
||||||
list.forEach(this::fill);
|
list.forEach(this::fill);
|
||||||
return list;
|
return list;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Cacheable(key = "'ALL'")
|
||||||
|
public List<MenuVO> list() {
|
||||||
|
MenuQuery menuQuery = new MenuQuery();
|
||||||
|
menuQuery.setStatus(DisEnableStatusEnum.ENABLE.getValue());
|
||||||
|
return super.list(menuQuery, null);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 检查名称是否存在
|
* 检查名称是否存在
|
||||||
*
|
*
|
||||||
|
@ -21,6 +21,7 @@ import java.util.stream.Collectors;
|
|||||||
|
|
||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
|
|
||||||
|
import org.springframework.cache.annotation.CacheEvict;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
import org.springframework.transaction.annotation.Transactional;
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
|
|
||||||
@ -30,6 +31,7 @@ import cn.hutool.core.util.ObjectUtil;
|
|||||||
|
|
||||||
import top.charles7c.cnadmin.auth.service.OnlineUserService;
|
import top.charles7c.cnadmin.auth.service.OnlineUserService;
|
||||||
import top.charles7c.cnadmin.common.base.BaseServiceImpl;
|
import top.charles7c.cnadmin.common.base.BaseServiceImpl;
|
||||||
|
import top.charles7c.cnadmin.common.constant.CacheConsts;
|
||||||
import top.charles7c.cnadmin.common.constant.SysConsts;
|
import top.charles7c.cnadmin.common.constant.SysConsts;
|
||||||
import top.charles7c.cnadmin.common.enums.DataScopeEnum;
|
import top.charles7c.cnadmin.common.enums.DataScopeEnum;
|
||||||
import top.charles7c.cnadmin.common.enums.DataTypeEnum;
|
import top.charles7c.cnadmin.common.enums.DataTypeEnum;
|
||||||
@ -82,6 +84,7 @@ public class RoleServiceImpl extends BaseServiceImpl<RoleMapper, RoleDO, RoleVO,
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@CacheEvict(cacheNames = CacheConsts.MENU_KEY_PREFIX, key = "#request.code == 'admin' ? 'ALL' : #request.code")
|
||||||
@Transactional(rollbackFor = Exception.class)
|
@Transactional(rollbackFor = Exception.class)
|
||||||
public void update(RoleRequest request, Long id) {
|
public void update(RoleRequest request, Long id) {
|
||||||
String name = request.getName();
|
String name = request.getName();
|
||||||
@ -167,15 +170,15 @@ public class RoleServiceImpl extends BaseServiceImpl<RoleMapper, RoleDO, RoleVO,
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Set<String> listCodeByUserId(Long userId) {
|
public Set<String> listCodeByUserId(Long userId) {
|
||||||
List<Long> roleIds = userRoleService.listRoleIdByUserId(userId);
|
List<Long> roleIdList = userRoleService.listRoleIdByUserId(userId);
|
||||||
List<RoleDO> roleList = baseMapper.lambdaQuery().select(RoleDO::getCode).in(RoleDO::getId, roleIds).list();
|
List<RoleDO> roleList = baseMapper.lambdaQuery().select(RoleDO::getCode).in(RoleDO::getId, roleIdList).list();
|
||||||
return roleList.stream().map(RoleDO::getCode).collect(Collectors.toSet());
|
return roleList.stream().map(RoleDO::getCode).collect(Collectors.toSet());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Set<RoleDTO> listByUserId(Long userId) {
|
public Set<RoleDTO> listByUserId(Long userId) {
|
||||||
List<Long> roleIds = userRoleService.listRoleIdByUserId(userId);
|
List<Long> roleIdList = userRoleService.listRoleIdByUserId(userId);
|
||||||
List<RoleDO> roleList = baseMapper.lambdaQuery().in(RoleDO::getId, roleIds).list();
|
List<RoleDO> roleList = baseMapper.lambdaQuery().in(RoleDO::getId, roleIdList).list();
|
||||||
return new HashSet<>(BeanUtil.copyToList(roleList, RoleDTO.class));
|
return new HashSet<>(BeanUtil.copyToList(roleList, RoleDTO.class));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -14,14 +14,12 @@
|
|||||||
AND t3.`status` = 1
|
AND t3.`status` = 1
|
||||||
</select>
|
</select>
|
||||||
|
|
||||||
<select id="selectListByUserId" resultType="top.charles7c.cnadmin.system.model.entity.MenuDO">
|
<select id="selectListByRoleCode" resultType="top.charles7c.cnadmin.system.model.entity.MenuDO">
|
||||||
SELECT t1.*
|
SELECT t1.*
|
||||||
FROM `sys_menu` AS t1
|
FROM `sys_menu` AS t1
|
||||||
LEFT JOIN `sys_role_menu` AS t2 ON t2.`menu_id` = t1.`id`
|
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`
|
LEFT JOIN `sys_role` AS t3 ON t3.`id` = t2.`role_id`
|
||||||
LEFT JOIN `sys_user_role` AS t4 ON t4.`role_id` = t3.`id`
|
WHERE t3.`code` = #{roleCode}
|
||||||
LEFT JOIN `sys_user` AS t5 ON t5.`id` = t4.`user_id`
|
|
||||||
WHERE t5.`id` = #{userId}
|
|
||||||
AND t1.`status` = 1
|
AND t1.`status` = 1
|
||||||
AND t3.`status` = 1
|
AND t3.`status` = 1
|
||||||
</select>
|
</select>
|
||||||
|
@ -45,6 +45,7 @@ import top.charles7c.cnadmin.common.util.RedisUtils;
|
|||||||
import top.charles7c.cnadmin.common.util.SecureUtils;
|
import top.charles7c.cnadmin.common.util.SecureUtils;
|
||||||
import top.charles7c.cnadmin.common.util.helper.LoginHelper;
|
import top.charles7c.cnadmin.common.util.helper.LoginHelper;
|
||||||
import top.charles7c.cnadmin.common.util.validate.ValidationUtils;
|
import top.charles7c.cnadmin.common.util.validate.ValidationUtils;
|
||||||
|
import top.charles7c.cnadmin.monitor.annotation.Log;
|
||||||
import top.charles7c.cnadmin.system.model.vo.UserDetailVO;
|
import top.charles7c.cnadmin.system.model.vo.UserDetailVO;
|
||||||
import top.charles7c.cnadmin.system.service.UserService;
|
import top.charles7c.cnadmin.system.service.UserService;
|
||||||
|
|
||||||
@ -92,6 +93,7 @@ public class LoginController {
|
|||||||
return R.ok();
|
return R.ok();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Log(ignore = true)
|
||||||
@Operation(summary = "获取用户信息", description = "获取登录用户信息")
|
@Operation(summary = "获取用户信息", description = "获取登录用户信息")
|
||||||
@GetMapping("/user/info")
|
@GetMapping("/user/info")
|
||||||
public R<UserInfoVO> getUserInfo() {
|
public R<UserInfoVO> getUserInfo() {
|
||||||
@ -103,9 +105,10 @@ public class LoginController {
|
|||||||
return R.ok(userInfoVO);
|
return R.ok(userInfoVO);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Log(ignore = true)
|
||||||
@Operation(summary = "获取路由信息", description = "获取登录用户的路由信息")
|
@Operation(summary = "获取路由信息", description = "获取登录用户的路由信息")
|
||||||
@GetMapping("/route")
|
@GetMapping("/route")
|
||||||
public R<List<RouteVO>> listMenu() {
|
public R<List<RouteVO>> listRoute() {
|
||||||
Long userId = LoginHelper.getUserId();
|
Long userId = LoginHelper.getUserId();
|
||||||
List<RouteVO> routeTree = loginService.buildRouteTree(userId);
|
List<RouteVO> routeTree = loginService.buildRouteTree(userId);
|
||||||
return R.ok(routeTree);
|
return R.ok(routeTree);
|
||||||
|
@ -50,7 +50,7 @@ spring.liquibase:
|
|||||||
# 配置文件路径
|
# 配置文件路径
|
||||||
change-log: classpath:/db/changelog/db.changelog-master.yaml
|
change-log: classpath:/db/changelog/db.changelog-master.yaml
|
||||||
|
|
||||||
--- ### Redis 单机配置
|
--- ### Redis 配置(单机版)
|
||||||
spring:
|
spring:
|
||||||
redis:
|
redis:
|
||||||
# 地址
|
# 地址
|
||||||
@ -65,6 +65,13 @@ spring:
|
|||||||
timeout: 10s
|
timeout: 10s
|
||||||
# 是否开启 SSL
|
# 是否开启 SSL
|
||||||
ssl: false
|
ssl: false
|
||||||
|
## Spring Cache 配置
|
||||||
|
cache:
|
||||||
|
redis:
|
||||||
|
# 缓存过期时长(单位:毫秒,默认 -1,表示永不过期)
|
||||||
|
time-to-live: 7200000
|
||||||
|
# 是否允许缓存空值(默认 true,表示允许,可以解决缓存穿透问题)
|
||||||
|
cache-null-values: true
|
||||||
|
|
||||||
--- ### 邮件配置
|
--- ### 邮件配置
|
||||||
spring.mail:
|
spring.mail:
|
||||||
|
@ -50,7 +50,7 @@ spring.liquibase:
|
|||||||
# 配置文件路径
|
# 配置文件路径
|
||||||
change-log: classpath:/db/changelog/db.changelog-master.yaml
|
change-log: classpath:/db/changelog/db.changelog-master.yaml
|
||||||
|
|
||||||
--- ### Redis 单机配置
|
--- ### Redis 配置(单机版)
|
||||||
spring:
|
spring:
|
||||||
redis:
|
redis:
|
||||||
# 地址
|
# 地址
|
||||||
@ -65,6 +65,13 @@ spring:
|
|||||||
timeout: 10s
|
timeout: 10s
|
||||||
# 是否开启 SSL
|
# 是否开启 SSL
|
||||||
ssl: false
|
ssl: false
|
||||||
|
## Spring Cache 配置
|
||||||
|
cache:
|
||||||
|
redis:
|
||||||
|
# 缓存过期时长(单位:毫秒,默认 -1,表示永不过期)
|
||||||
|
time-to-live: 7200000
|
||||||
|
# 是否允许缓存空值(默认 true,表示允许,可以解决缓存穿透问题)
|
||||||
|
cache-null-values: true
|
||||||
|
|
||||||
--- ### 邮件配置
|
--- ### 邮件配置
|
||||||
spring.mail:
|
spring.mail:
|
||||||
|
@ -212,14 +212,6 @@ spring:
|
|||||||
deserialization:
|
deserialization:
|
||||||
# 允许反序列化不存在的属性
|
# 允许反序列化不存在的属性
|
||||||
FAIL_ON_UNKNOWN_PROPERTIES: false
|
FAIL_ON_UNKNOWN_PROPERTIES: false
|
||||||
## 缓存配置(@Cacheable)
|
|
||||||
cache:
|
|
||||||
type: redis
|
|
||||||
redis:
|
|
||||||
# 缓存过期时长(单位:毫秒,默认 -1,表示永不过期)
|
|
||||||
time-to-live: 7200000
|
|
||||||
# 是否允许缓存空值(默认 true,表示允许,可以解决缓存穿透问题)
|
|
||||||
cache-null-values: true
|
|
||||||
|
|
||||||
--- ### 健康检查配置
|
--- ### 健康检查配置
|
||||||
management.health:
|
management.health:
|
||||||
|
Loading…
Reference in New Issue
Block a user