瀏覽代碼

初步整合完成

yq 3 年之前
父節點
當前提交
e407ca9fa6

+ 2 - 0
fiveep-common/fiveep-common-spring/src/main/java/com/bizmatics/common/spring/config/redis/RedisHelper.java

@@ -8,6 +8,7 @@ import org.springframework.data.redis.connection.DataType;
 import org.springframework.data.redis.core.*;
 import org.springframework.data.redis.core.script.DefaultRedisScript;
 import org.springframework.data.redis.core.script.RedisScript;
+import org.springframework.stereotype.Component;
 
 import java.util.*;
 import java.util.concurrent.TimeUnit;
@@ -19,6 +20,7 @@ import java.util.stream.Collectors;
  * @author chenpeng
  * Create at February 18, 2019 at 16:04:36 GMT+8
  */
+@Component
 public final class RedisHelper {
 
     private static final Logger LOGGER = LoggerFactory.getLogger(RedisHelper.class);

+ 0 - 2
fiveep-controller/src/main/java/com/bizmatics/controller/DemoControllerApplication.java

@@ -3,14 +3,12 @@ package com.bizmatics.controller;
 import org.mybatis.spring.annotation.MapperScan;
 import org.springframework.boot.SpringApplication;
 import org.springframework.boot.autoconfigure.SpringBootApplication;
-import org.springframework.cloud.openfeign.EnableFeignClients;
 import org.springframework.context.annotation.ComponentScan;
 import org.springframework.data.elasticsearch.repository.config.EnableElasticsearchRepositories;
 import org.springframework.scheduling.annotation.EnableScheduling;
 import org.springframework.transaction.annotation.EnableTransactionManagement;
 
 @EnableElasticsearchRepositories(basePackages = "com.bizmatics.persistence.mapper.es")
-@EnableFeignClients("com.bizmatics")
 @ComponentScan("com.bizmatics")
 @SpringBootApplication
 @EnableTransactionManagement

+ 23 - 0
fiveep-service/src/main/java/com/bizmatics/service/aop/RepeatSubmit.java

@@ -0,0 +1,23 @@
+package com.bizmatics.service.aop;
+
+import java.lang.annotation.Documented;
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Inherited;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * 自定义注解防止表单重复提交
+ * 
+ * @author ruoyi
+ *
+ */
+@Inherited
+@Target(ElementType.METHOD)
+@Retention(RetentionPolicy.RUNTIME)
+@Documented
+public @interface RepeatSubmit
+{
+
+}

+ 64 - 0
fiveep-service/src/main/java/com/bizmatics/service/config/ResourcesConfig.java

@@ -0,0 +1,64 @@
+package com.bizmatics.service.config;
+
+
+import com.bizmatics.service.interceptor.RepeatSubmitInterceptor;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.web.cors.CorsConfiguration;
+import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
+import org.springframework.web.filter.CorsFilter;
+import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
+import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
+import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
+
+/**
+ * 通用配置
+ * 
+ * @author ruoyi
+ */
+@Configuration
+public class ResourcesConfig implements WebMvcConfigurer
+{
+    @Autowired
+    private RepeatSubmitInterceptor repeatSubmitInterceptor;
+
+    @Override
+    public void addResourceHandlers(ResourceHandlerRegistry registry)
+    {
+//        /** 本地文件上传路径 */
+//        registry.addResourceHandler(Constants.RESOURCE_PREFIX + "/**").addResourceLocations("file:" + RuoYiConfig.getProfile() + "/");
+//
+//        /** swagger配置 */
+//        registry.addResourceHandler("/swagger-ui/**").addResourceLocations("classpath:/META-INF/resources/webjars/springfox-swagger-ui/");
+    }
+
+    /**
+     * 自定义拦截规则
+     */
+    @Override
+    public void addInterceptors(InterceptorRegistry registry)
+    {
+        registry.addInterceptor(repeatSubmitInterceptor).addPathPatterns("/**");
+    }
+
+    /**
+     * 跨域配置
+     */
+    @Bean
+    public CorsFilter corsFilter()
+    {
+        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
+        CorsConfiguration config = new CorsConfiguration();
+        config.setAllowCredentials(true);
+        // 设置访问源地址
+        config.addAllowedOrigin("*");
+        // 设置访问源请求头
+        config.addAllowedHeader("*");
+        // 设置访问源请求方法
+        config.addAllowedMethod("*");
+        // 对接口配置跨域设置
+        source.registerCorsConfiguration("/**", config);
+        return new CorsFilter(source);
+    }
+}

+ 2 - 2
fiveep-service/src/main/java/com/bizmatics/service/config/SecurityConfig.java

@@ -1,5 +1,6 @@
 package com.bizmatics.service.config;
 
+import com.bizmatics.service.config.security.UserDetailsServiceImpl;
 import com.bizmatics.service.config.security.filter.JwtAuthenticationTokenFilter;
 import com.bizmatics.service.config.security.handle.AuthenticationEntryPointImpl;
 import com.bizmatics.service.config.security.handle.LogoutSuccessHandlerImpl;
@@ -12,7 +13,6 @@ import org.springframework.security.config.annotation.method.configuration.Enabl
 import org.springframework.security.config.annotation.web.builders.HttpSecurity;
 import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
 import org.springframework.security.config.http.SessionCreationPolicy;
-import org.springframework.security.core.userdetails.UserDetailsService;
 import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
 import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
 import org.springframework.security.web.authentication.logout.LogoutFilter;
@@ -31,7 +31,7 @@ public class SecurityConfig extends WebSecurityConfigurerAdapter
      * 自定义用户认证逻辑
      */
     @Autowired
-    private UserDetailsService userDetailsService;
+    private UserDetailsServiceImpl userDetailsService;
     
     /**
      * 认证失败处理类

+ 62 - 0
fiveep-service/src/main/java/com/bizmatics/service/config/security/UserDetailsServiceImpl.java

@@ -0,0 +1,62 @@
+package com.bizmatics.service.config.security;
+
+import com.bizmatics.common.core.exception.BusinessException;
+import com.bizmatics.model.system.SysUser;
+import com.bizmatics.service.enums.UserStatus;
+import com.bizmatics.service.system.ISysUserService;
+import com.bizmatics.service.system.impl.SysPermissionService;
+import com.bizmatics.service.util.LoginUser;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.security.core.userdetails.UserDetails;
+import org.springframework.security.core.userdetails.UserDetailsService;
+import org.springframework.security.core.userdetails.UsernameNotFoundException;
+import org.springframework.stereotype.Service;
+
+import java.util.Objects;
+
+/**
+ * 用户验证处理
+ *
+ * @author ruoyi
+ */
+@Service
+public class UserDetailsServiceImpl implements UserDetailsService
+{
+    private static final Logger log = LoggerFactory.getLogger(UserDetailsServiceImpl.class);
+
+    @Autowired
+    private ISysUserService userService;
+
+    @Autowired
+    private SysPermissionService permissionService;
+
+    @Override
+    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException
+    {
+        SysUser user = userService.selectUserByUserName(username);
+        if (Objects.isNull(user))
+        {
+            log.info("登录用户:{} 不存在.", username);
+            throw new UsernameNotFoundException("登录用户:" + username + " 不存在");
+        }
+        else if (UserStatus.DELETED.getCode().equals(user.getDelFlag()))
+        {
+            log.info("登录用户:{} 已被删除.", username);
+            throw new BusinessException("对不起,您的账号:" + username + " 已被删除");
+        }
+        else if (UserStatus.DISABLE.getCode().equals(user.getStatus()))
+        {
+            log.info("登录用户:{} 已被停用.", username);
+            throw new BusinessException("对不起,您的账号:" + username + " 已停用");
+        }
+
+        return createLoginUser(user);
+    }
+
+    public UserDetails createLoginUser(SysUser user)
+    {
+        return new LoginUser(user, permissionService.getMenuPermission(user));
+    }
+}

+ 30 - 0
fiveep-service/src/main/java/com/bizmatics/service/enums/UserStatus.java

@@ -0,0 +1,30 @@
+package com.bizmatics.service.enums;
+
+/**
+ * 用户状态
+ * 
+ * @author ruoyi
+ */
+public enum UserStatus
+{
+    OK("0", "正常"), DISABLE("1", "停用"), DELETED("2", "删除");
+
+    private final String code;
+    private final String info;
+
+    UserStatus(String code, String info)
+    {
+        this.code = code;
+        this.info = info;
+    }
+
+    public String getCode()
+    {
+        return code;
+    }
+
+    public String getInfo()
+    {
+        return info;
+    }
+}

+ 58 - 0
fiveep-service/src/main/java/com/bizmatics/service/interceptor/RepeatSubmitInterceptor.java

@@ -0,0 +1,58 @@
+package com.bizmatics.service.interceptor;
+
+import com.bizmatics.common.core.bean.ApiResult;
+import com.bizmatics.common.core.exception.SystemErrorCode;
+import com.bizmatics.common.mvc.utils.ServletUtils;
+import com.bizmatics.common.spring.util.JsonUtils;
+import com.bizmatics.service.aop.RepeatSubmit;
+import org.springframework.stereotype.Component;
+import org.springframework.web.method.HandlerMethod;
+import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.lang.reflect.Method;
+
+
+/**
+ * 防止重复提交拦截器
+ *
+ * @author ruoyi
+ */
+@Component
+public abstract class RepeatSubmitInterceptor extends HandlerInterceptorAdapter
+{
+    @Override
+    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception
+    {
+        if (handler instanceof HandlerMethod)
+        {
+            HandlerMethod handlerMethod = (HandlerMethod) handler;
+            Method method = handlerMethod.getMethod();
+            RepeatSubmit annotation = method.getAnnotation(RepeatSubmit.class);
+            if (annotation != null)
+            {
+                if (this.isRepeatSubmit(request))
+                {
+                    ApiResult<Object> error = ApiResult.error(SystemErrorCode.SYS_SYSTEM_ERROR.getCode(), "不允许重复提交,请稍后再试");
+                    ServletUtils.renderString(response, JsonUtils.toJson(error));
+                    return false;
+                }
+            }
+            return true;
+        }
+        else
+        {
+            return super.preHandle(request, response, handler);
+        }
+    }
+
+    /**
+     * 验证是否重复提交由子类实现具体的防重复提交的规则
+     *
+     * @param request
+     * @return
+     * @throws Exception
+     */
+    public abstract boolean isRepeatSubmit(HttpServletRequest request);
+}

+ 127 - 0
fiveep-service/src/main/java/com/bizmatics/service/interceptor/impl/SameUrlDataInterceptor.java

@@ -0,0 +1,127 @@
+package com.bizmatics.service.interceptor.impl;
+
+import com.baomidou.mybatisplus.core.toolkit.StringUtils;
+import com.bizmatics.common.spring.config.redis.RedisHelper;
+import com.bizmatics.common.spring.util.JsonUtils;
+import com.bizmatics.model.constants.Constants;
+import com.bizmatics.service.filter.RepeatedlyRequestWrapper;
+import com.bizmatics.service.interceptor.RepeatSubmitInterceptor;
+import com.bizmatics.service.util.HttpHelper;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.stereotype.Component;
+
+import javax.servlet.http.HttpServletRequest;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.concurrent.TimeUnit;
+
+
+/**
+ * 判断请求url和数据是否和上一次相同,
+ * 如果和上次相同,则是重复提交表单。 有效时间为10秒内。
+ * 
+ * @author ruoyi
+ */
+@Component
+public class SameUrlDataInterceptor extends RepeatSubmitInterceptor
+{
+    public final String REPEAT_PARAMS = "repeatParams";
+
+    public final String REPEAT_TIME = "repeatTime";
+
+    // 令牌自定义标识
+    @Value("${token.header}")
+    private String header;
+
+    @Autowired
+    private RedisHelper redisHelper;
+
+    /**
+     * 间隔时间,单位:秒 默认10秒
+     * 
+     * 两次相同参数的请求,如果间隔时间大于该参数,系统不会认定为重复提交的数据
+     */
+    private int intervalTime = 10;
+
+    public void setIntervalTime(int intervalTime)
+    {
+        this.intervalTime = intervalTime;
+    }
+
+    @SuppressWarnings("unchecked")
+    @Override
+    public boolean isRepeatSubmit(HttpServletRequest request)
+    {
+        String nowParams = "";
+        if (request instanceof RepeatedlyRequestWrapper)
+        {
+            RepeatedlyRequestWrapper repeatedlyRequest = (RepeatedlyRequestWrapper) request;
+            nowParams = HttpHelper.getBodyString(repeatedlyRequest);
+        }
+
+        // body参数为空,获取Parameter的数据
+        if (StringUtils.isBlank(nowParams))
+        {
+            nowParams = JsonUtils.toJson(request.getParameterMap());
+        }
+        Map<String, Object> nowDataMap = new HashMap<String, Object>();
+        nowDataMap.put(REPEAT_PARAMS, nowParams);
+        nowDataMap.put(REPEAT_TIME, System.currentTimeMillis());
+
+        // 请求地址(作为存放cache的key值)
+        String url = request.getRequestURI();
+
+        // 唯一值(没有消息头则使用请求地址)
+        String submitKey = request.getHeader(header);
+        if (StringUtils.isEmpty(submitKey))
+        {
+            submitKey = url;
+        }
+
+        // 唯一标识(指定key + 消息头)
+        String cacheRepeatKey = Constants.REPEAT_SUBMIT_KEY + submitKey;
+
+        Object sessionObj = redisHelper.get(cacheRepeatKey);
+        if (sessionObj != null)
+        {
+            Map<String, Object> sessionMap = (Map<String, Object>) sessionObj;
+            if (sessionMap.containsKey(url))
+            {
+                Map<String, Object> preDataMap = (Map<String, Object>) sessionMap.get(url);
+                if (compareParams(nowDataMap, preDataMap) && compareTime(nowDataMap, preDataMap))
+                {
+                    return true;
+                }
+            }
+        }
+        Map<String, Object> cacheMap = new HashMap<String, Object>();
+        cacheMap.put(url, nowDataMap);
+        redisHelper.set(cacheRepeatKey, cacheMap, intervalTime, TimeUnit.SECONDS);
+        return false;
+    }
+
+    /**
+     * 判断参数是否相同
+     */
+    private boolean compareParams(Map<String, Object> nowMap, Map<String, Object> preMap)
+    {
+        String nowParams = (String) nowMap.get(REPEAT_PARAMS);
+        String preParams = (String) preMap.get(REPEAT_PARAMS);
+        return nowParams.equals(preParams);
+    }
+
+    /**
+     * 判断两次间隔时间
+     */
+    private boolean compareTime(Map<String, Object> nowMap, Map<String, Object> preMap)
+    {
+        long time1 = (Long) nowMap.get(REPEAT_TIME);
+        long time2 = (Long) preMap.get(REPEAT_TIME);
+        if ((time1 - time2) < (this.intervalTime * 1000))
+        {
+            return true;
+        }
+        return false;
+    }
+}

+ 12 - 3
fiveep-service/src/main/java/com/bizmatics/service/util/DictUtils.java

@@ -2,8 +2,10 @@ package com.bizmatics.service.util;
 
 import com.bizmatics.common.core.util.StringUtils;
 import com.bizmatics.common.spring.config.redis.RedisHelper;
+import com.bizmatics.common.spring.util.SpringContextUtils;
 import com.bizmatics.model.constants.Constants;
 import com.bizmatics.model.system.SysDictData;
+import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Component;
 
 import java.util.Collection;
@@ -23,6 +25,7 @@ public class DictUtils
      * 分隔符
      */
     public static final String SEPARATOR = ",";
+    @Autowired
     private static RedisHelper redisHelper;
 
     /**
@@ -33,7 +36,7 @@ public class DictUtils
      */
     public static void setDictCache(String key, List<SysDictData> dictDatas)
     {
-        redisHelper.set(getCacheKey(key), dictDatas);
+        getRedisHelper().set(getCacheKey(key), dictDatas);
     }
 
     /**
@@ -44,7 +47,7 @@ public class DictUtils
      */
     public static List<SysDictData> getDictCache(String key)
     {
-        Object cacheObj = redisHelper.get(getCacheKey(key));
+        Object cacheObj = getRedisHelper().get(getCacheKey(key));
         if (Objects.nonNull(cacheObj))
         {
             List<SysDictData> dictDatas = (List<SysDictData>) cacheObj;
@@ -164,7 +167,7 @@ public class DictUtils
      */
     public static void removeDictCache(String key)
     {
-        redisHelper.delete(getCacheKey(key));
+        getRedisHelper().delete(getCacheKey(key));
     }
 
     /**
@@ -172,6 +175,7 @@ public class DictUtils
      */
     public static void clearDictCache()
     {
+        RedisHelper redisHelper = getRedisHelper();
         Collection<String> keys = redisHelper.keys(Constants.SYS_DICT_KEY + "*");
         redisHelper.delete(keys);
     }
@@ -186,4 +190,9 @@ public class DictUtils
     {
         return Constants.SYS_DICT_KEY + configKey;
     }
+
+
+    private static RedisHelper getRedisHelper() {
+        return DictUtils.redisHelper == null ? SpringContextUtils.getBean(RedisHelper.class) : DictUtils.redisHelper;
+    }
 }