cache
This commit is contained in:
parent
92138bac2a
commit
0da00b9837
|
|
@ -118,6 +118,11 @@
|
||||||
<artifactId>querydsl-jpa</artifactId>
|
<artifactId>querydsl-jpa</artifactId>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-configuration-processor</artifactId>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
|
||||||
</project>
|
</project>
|
||||||
|
|
@ -1,23 +0,0 @@
|
||||||
package com.ruoyi.common.annotation;
|
|
||||||
|
|
||||||
import java.lang.annotation.Documented;
|
|
||||||
import java.lang.annotation.ElementType;
|
|
||||||
import java.lang.annotation.Retention;
|
|
||||||
import java.lang.annotation.RetentionPolicy;
|
|
||||||
import java.lang.annotation.Target;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 数据权限过滤注解
|
|
||||||
*
|
|
||||||
* @author ruoyi
|
|
||||||
*/
|
|
||||||
@Target(ElementType.TYPE)
|
|
||||||
@Retention(RetentionPolicy.RUNTIME)
|
|
||||||
@Documented
|
|
||||||
public @interface DataScope {
|
|
||||||
/**
|
|
||||||
* 业务表的所属用户的字段名称:过滤仅本人的数据权限,
|
|
||||||
* 该字段的类型为:{@link com.ruoyi.system.domain.SysUser}
|
|
||||||
*/
|
|
||||||
String userFieldName() default "";
|
|
||||||
}
|
|
||||||
|
|
@ -0,0 +1,25 @@
|
||||||
|
package com.ruoyi.common.properties;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.ToString;
|
||||||
|
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
import java.time.Duration;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
@ToString
|
||||||
|
@Component
|
||||||
|
@ConfigurationProperties(prefix = "cache")
|
||||||
|
public class CacheProperties {
|
||||||
|
|
||||||
|
private Map<String, Config> names = new HashMap<>();
|
||||||
|
|
||||||
|
@ToString
|
||||||
|
@Data
|
||||||
|
public static class Config{
|
||||||
|
private Duration ttl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1,122 +0,0 @@
|
||||||
package com.ruoyi.framework.aspectj;
|
|
||||||
|
|
||||||
import com.querydsl.core.types.ExpressionUtils;
|
|
||||||
import com.querydsl.core.types.Predicate;
|
|
||||||
import com.ruoyi.common.annotation.DataScope;
|
|
||||||
import com.ruoyi.common.core.domain.BaseEntity;
|
|
||||||
import com.ruoyi.common.utils.StringUtils;
|
|
||||||
import com.ruoyi.framework.util.ShiroUtils;
|
|
||||||
import com.ruoyi.system.domain.SysRole;
|
|
||||||
import com.ruoyi.system.domain.SysUser;
|
|
||||||
import com.ruoyi.system.service.ISysUserService;
|
|
||||||
import org.aspectj.lang.JoinPoint;
|
|
||||||
import org.aspectj.lang.Signature;
|
|
||||||
import org.aspectj.lang.annotation.After;
|
|
||||||
import org.aspectj.lang.annotation.Aspect;
|
|
||||||
import org.aspectj.lang.annotation.Before;
|
|
||||||
import org.aspectj.lang.annotation.Pointcut;
|
|
||||||
import org.aspectj.lang.reflect.MethodSignature;
|
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
|
||||||
import org.springframework.stereotype.Component;
|
|
||||||
|
|
||||||
import javax.persistence.EntityManager;
|
|
||||||
import javax.persistence.PersistenceContext;
|
|
||||||
import javax.persistence.criteria.CriteriaBuilder;
|
|
||||||
import javax.persistence.criteria.Root;
|
|
||||||
import java.lang.reflect.Method;
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Set;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 数据过滤处理
|
|
||||||
*
|
|
||||||
* @author ruoyi
|
|
||||||
*/
|
|
||||||
@Aspect
|
|
||||||
@Component
|
|
||||||
public class DataScopeAspect {
|
|
||||||
|
|
||||||
@Autowired
|
|
||||||
private ISysUserService userService;
|
|
||||||
@PersistenceContext
|
|
||||||
private EntityManager entityManager;
|
|
||||||
|
|
||||||
// 配置织入点
|
|
||||||
@Pointcut("@annotation(com.ruoyi.common.annotation.DataScope)")
|
|
||||||
public void dataScopePointCut() {
|
|
||||||
}
|
|
||||||
|
|
||||||
@Before("dataScopePointCut()")
|
|
||||||
public void doBefore(JoinPoint point) throws Throwable {
|
|
||||||
handleDataScope(point);
|
|
||||||
}
|
|
||||||
|
|
||||||
@After("dataScopePointCut()")
|
|
||||||
public void doAfter(JoinPoint point) throws Throwable{
|
|
||||||
DataScopeContextHolder.clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
protected void handleDataScope(final JoinPoint joinPoint) {
|
|
||||||
// 获得注解
|
|
||||||
SysUser currentUser = ShiroUtils.getSysUser();
|
|
||||||
DataScope controllerDataScope = getAnnotationLog(joinPoint);
|
|
||||||
|
|
||||||
if (controllerDataScope == null) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
// 获取当前的用户
|
|
||||||
|
|
||||||
if (currentUser != null) {
|
|
||||||
// 如果是超级管理员,则不过滤数据
|
|
||||||
if (!currentUser.isAdmin()) {
|
|
||||||
dataScopeFilter(joinPoint, currentUser, controllerDataScope);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 数据范围过滤
|
|
||||||
*
|
|
||||||
* @param joinPoint 切点
|
|
||||||
* @param user 用户
|
|
||||||
*/
|
|
||||||
private void dataScopeFilter(JoinPoint joinPoint, SysUser user, DataScope controllerDataScope) {
|
|
||||||
user = userService.selectUserWithRolesAndPostsById(user.getUserId());
|
|
||||||
|
|
||||||
CriteriaBuilder criteriaBuilder = entityManager.getCriteriaBuilder();
|
|
||||||
List<Predicate> predicates = new ArrayList<>();
|
|
||||||
Set<SysRole> roles = user.getRoles();
|
|
||||||
for(SysRole sysRole : roles){
|
|
||||||
switch (sysRole.getDataScope()){
|
|
||||||
case DATA_SCOPE_DEPT: //当前部门
|
|
||||||
break;
|
|
||||||
case DATA_SCOPE_SELF: //自己
|
|
||||||
break;
|
|
||||||
case DATA_SCOPE_CUSTOM: //自定义
|
|
||||||
break;
|
|
||||||
case DATA_SCOPE_DEPT_AND_CHILD: //子部门
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
//无需过滤
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
DataScopeContextHolder.set(ExpressionUtils.anyOf(predicates));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 是否存在注解,如果存在就获取
|
|
||||||
*/
|
|
||||||
private DataScope getAnnotationLog(JoinPoint joinPoint) {
|
|
||||||
Signature signature = joinPoint.getSignature();
|
|
||||||
MethodSignature methodSignature = (MethodSignature) signature;
|
|
||||||
Method method = methodSignature.getMethod();
|
|
||||||
|
|
||||||
if (method != null) {
|
|
||||||
return method.getAnnotation(DataScope.class);
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,20 +0,0 @@
|
||||||
package com.ruoyi.framework.aspectj;
|
|
||||||
|
|
||||||
import com.querydsl.core.types.Predicate;
|
|
||||||
|
|
||||||
public class DataScopeContextHolder {
|
|
||||||
|
|
||||||
private static ThreadLocal<Predicate> threadLocal = new ThreadLocal<>();
|
|
||||||
|
|
||||||
public static void set(Predicate predicate){
|
|
||||||
threadLocal.set(predicate);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void clear(){
|
|
||||||
threadLocal.remove();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Predicate get(){
|
|
||||||
return threadLocal.get();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -0,0 +1,69 @@
|
||||||
|
package com.ruoyi.framework.config;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.annotation.JsonTypeInfo;
|
||||||
|
import com.fasterxml.jackson.databind.DeserializationFeature;
|
||||||
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||||
|
import com.fasterxml.jackson.databind.module.SimpleModule;
|
||||||
|
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
|
||||||
|
import com.ruoyi.common.properties.CacheProperties;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.boot.autoconfigure.AutoConfigureAfter;
|
||||||
|
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
|
||||||
|
import org.springframework.cache.CacheManager;
|
||||||
|
import org.springframework.cache.annotation.EnableCaching;
|
||||||
|
import org.springframework.context.annotation.Bean;
|
||||||
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
import org.springframework.data.redis.cache.RedisCacheConfiguration;
|
||||||
|
import org.springframework.data.redis.cache.RedisCacheManager;
|
||||||
|
import org.springframework.data.redis.cache.RedisCacheWriter;
|
||||||
|
import org.springframework.data.redis.connection.RedisConnectionFactory;
|
||||||
|
import org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer;
|
||||||
|
import org.springframework.data.redis.serializer.RedisSerializationContext;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
@ConditionalOnClass(name = "org.springframework.data.redis.connection.RedisConnectionFactory")
|
||||||
|
@EnableCaching
|
||||||
|
@Configuration
|
||||||
|
@AutoConfigureAfter(CacheProperties.class)
|
||||||
|
public class CacheConfig {
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private RedisConnectionFactory factory;
|
||||||
|
@Autowired
|
||||||
|
private CacheProperties cacheProperties;
|
||||||
|
@Autowired
|
||||||
|
private GenericJackson2JsonRedisSerializer genericJackson2JsonRedisSerializer;
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
public RedisCacheWriter writer(){
|
||||||
|
return RedisCacheWriter.nonLockingRedisCacheWriter(factory);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
public CacheManager cacheManager() {
|
||||||
|
Map<String, RedisCacheConfiguration> configurationMap = new HashMap<>();
|
||||||
|
for(String key : cacheProperties.getNames().keySet()){
|
||||||
|
configurationMap.put(key, RedisCacheConfiguration.defaultCacheConfig()
|
||||||
|
.disableCachingNullValues()
|
||||||
|
.serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(genericJackson2JsonRedisSerializer))
|
||||||
|
.entryTtl(cacheProperties.getNames().get(key).getTtl()));
|
||||||
|
}
|
||||||
|
return RedisCacheManager.builder(factory)
|
||||||
|
.initialCacheNames(cacheProperties.getNames().keySet())
|
||||||
|
.withInitialCacheConfigurations(configurationMap)
|
||||||
|
.build();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
public GenericJackson2JsonRedisSerializer genericJackson2JsonRedisSerializer(){
|
||||||
|
ObjectMapper objectMapper = new ObjectMapper();
|
||||||
|
SimpleModule simpleModule = new SimpleModule();
|
||||||
|
objectMapper.registerModule(simpleModule);
|
||||||
|
objectMapper.registerModule(new JavaTimeModule());
|
||||||
|
objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
|
||||||
|
objectMapper.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL, JsonTypeInfo.As.PROPERTY);
|
||||||
|
return new GenericJackson2JsonRedisSerializer(objectMapper);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -2,7 +2,6 @@ package com.ruoyi.system.service.impl;
|
||||||
|
|
||||||
import com.querydsl.core.types.ExpressionUtils;
|
import com.querydsl.core.types.ExpressionUtils;
|
||||||
import com.querydsl.core.types.Predicate;
|
import com.querydsl.core.types.Predicate;
|
||||||
import com.ruoyi.common.annotation.DataScope;
|
|
||||||
import com.ruoyi.common.constant.UserConstants;
|
import com.ruoyi.common.constant.UserConstants;
|
||||||
import com.ruoyi.common.core.domain.BaseEntity;
|
import com.ruoyi.common.core.domain.BaseEntity;
|
||||||
import com.ruoyi.common.core.text.Convert;
|
import com.ruoyi.common.core.text.Convert;
|
||||||
|
|
@ -29,7 +28,6 @@ import java.util.*;
|
||||||
*
|
*
|
||||||
* @author ruoyi
|
* @author ruoyi
|
||||||
*/
|
*/
|
||||||
@DataScope(userFieldName = "user")
|
|
||||||
@Service
|
@Service
|
||||||
public class SysRoleServiceImpl extends BusinessService implements ISysRoleService {
|
public class SysRoleServiceImpl extends BusinessService implements ISysRoleService {
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue