Przeglądaj źródła

接口限流&RSA验签

yinhao 4 lat temu
rodzic
commit
8ba5db734e
36 zmienionych plików z 2162 dodań i 5 usunięć
  1. 58 0
      huimv-smart-apiservice/src/main/java/com/huimv/apiservice/http/HttpUrlUtils.java
  2. 72 0
      huimv-smart-apiservice/src/main/java/com/huimv/apiservice/limit/LimitAspect.java
  3. 34 0
      huimv-smart-apiservice/src/main/java/com/huimv/apiservice/limit/LimitKey.java
  4. 45 0
      huimv-smart-apiservice/src/main/java/com/huimv/apiservice/utils/ApiSignCreate.java
  5. 12 0
      huimv-smart-apiservice/src/main/java/com/huimv/apiservice/utils/ApiVerifyUtil.java
  6. 134 0
      huimv-smart-apiservice/src/main/java/com/huimv/apiservice/utils/SimpleApiSignInterceptor.java
  7. 19 1
      huimv-smart-common/pom.xml
  8. 15 0
      huimv-smart-common/src/main/java/com/huimv/common/exception/LimitAccessException.java
  9. 6 0
      huimv-smart-common/src/main/java/com/huimv/common/exception/RRExceptionHandler.java
  10. 21 0
      huimv-smart-common/src/main/java/com/huimv/common/utils/HttpContextUtil.java
  11. 66 0
      huimv-smart-common/src/main/java/com/huimv/common/utils/IPUtil.java
  12. 611 0
      huimv-smart-common/src/main/java/com/huimv/common/utils/RedisUtil.java
  13. 1 1
      huimv-smart-gateway/src/main/resources/application.yml
  14. 25 0
      huimv-smart-management/src/main/java/com/huimv/management/Abc.java
  15. 46 0
      huimv-smart-management/src/main/java/com/huimv/management/config/RedisConfigure.java
  16. 88 0
      huimv-smart-management/src/main/java/com/huimv/management/controller/TestController.java
  17. 17 0
      huimv-smart-management/src/main/java/com/huimv/management/dao/TestDao.java
  18. 36 0
      huimv-smart-management/src/main/java/com/huimv/management/entity/TestEntity.java
  19. 51 0
      huimv-smart-management/src/main/java/com/huimv/management/limit/annotation/Limit.java
  20. 44 0
      huimv-smart-management/src/main/java/com/huimv/management/limit/aspect/AspectSupport.java
  21. 110 0
      huimv-smart-management/src/main/java/com/huimv/management/limit/aspect/LimitAspect.java
  22. 19 0
      huimv-smart-management/src/main/java/com/huimv/management/limit/enums/LimitType.java
  23. 89 0
      huimv-smart-management/src/main/java/com/huimv/management/rsa/ClientController.java
  24. 62 0
      huimv-smart-management/src/main/java/com/huimv/management/rsa/GeneratorRSAKey.java
  25. 84 0
      huimv-smart-management/src/main/java/com/huimv/management/rsa/JdkSignatureUtil.java
  26. 202 0
      huimv-smart-management/src/main/java/com/huimv/management/rsa/RSA.java
  27. 35 0
      huimv-smart-management/src/main/java/com/huimv/management/rsa/RSAUtil.java
  28. 48 0
      huimv-smart-management/src/main/java/com/huimv/management/rsa/ServerController.java
  29. 38 0
      huimv-smart-management/src/main/java/com/huimv/management/rsa/SignRSAUtil.java
  30. 20 0
      huimv-smart-management/src/main/java/com/huimv/management/service/TestService.java
  31. 29 0
      huimv-smart-management/src/main/java/com/huimv/management/service/impl/TestServiceImpl.java
  32. 1 1
      huimv-smart-management/src/main/resources/application-dev.yml
  33. 14 0
      huimv-smart-management/src/main/resources/mapper/management/TestDao.xml
  34. 6 0
      renren-fast/pom.xml
  35. 3 1
      renren-fast/src/main/java/io/renren/RenrenApplication.java
  36. 1 1
      renren-generator/src/main/resources/application.yml

+ 58 - 0
huimv-smart-apiservice/src/main/java/com/huimv/apiservice/http/HttpUrlUtils.java

@@ -0,0 +1,58 @@
+package com.huimv.apiservice.http;
+
+import java.io.BufferedReader;
+import java.io.DataOutputStream;
+import java.io.InputStreamReader;
+import java.net.HttpURLConnection;
+import java.net.URL;
+
+/**
+ * @Author yinhao
+ * @Date 2021/4/28 18:13
+ * @Description
+ */
+public class HttpUrlUtils {
+
+    public static String httpURLConnectionPOST (String url, String data) {
+        StringBuffer strBf = new StringBuffer();
+        try {
+            URL realUrl = new URL(url);
+            //将realUrl以 open方法返回的urlConnection  连接强转为HttpURLConnection连接  (标识一个url所引用的远程对象连接)
+            HttpURLConnection connection = (HttpURLConnection) realUrl.openConnection();// 此时cnnection只是为一个连接对象,待连接中
+            //设置连接输出流为true,默认false (post请求是以流的方式隐式的传递参数)
+            connection.setDoOutput(true);
+            //设置连接输入流为true
+            connection.setDoInput(true);
+            //设置请求方式为post
+            connection.setRequestMethod("POST");
+            //post请求缓存设为false
+            connection.setUseCaches(false);
+            //设置该HttpURLConnection实例是否自动执行重定向
+            connection.setInstanceFollowRedirects(true);
+            //设置请求头里面的各个属性 (以下为设置内容的类型,设置为经过urlEncoded编码过的from参数)
+            connection.setRequestProperty("Content-Type", "application/json;charset=utf-8");
+            //建立连接 (请求未开始,直到connection.getInputStream()方法调用时才发起,以上各个参数设置需在此方法之前进行)
+            connection.connect();
+            //创建输入输出流,用于往连接里面输出携带的参数,(输出内容为?后面的内容)
+            DataOutputStream dataout = new DataOutputStream(connection.getOutputStream());
+            String query = data.toString();
+            //将参数输出到连接
+            dataout.write(query.getBytes("UTF-8"));
+            // 输出完成后刷新并关闭流
+            dataout.flush();
+            dataout.close(); // 重要且易忽略步骤 (关闭流,切记!)
+            BufferedReader reader = new BufferedReader(new InputStreamReader(connection.getInputStream(), "UTF-8"));
+            String lines;
+            while ((lines = reader.readLine()) != null) {
+                lines = new String(lines.getBytes(), "utf-8");
+                strBf.append(lines);
+            }
+            reader.close();
+            connection.disconnect();
+            System.out.println("返回数据:"+strBf.toString());
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+        return strBf.toString();
+    }
+}

+ 72 - 0
huimv-smart-apiservice/src/main/java/com/huimv/apiservice/limit/LimitAspect.java

@@ -0,0 +1,72 @@
+package com.huimv.apiservice.limit;
+
+import org.aspectj.lang.ProceedingJoinPoint;
+import org.aspectj.lang.annotation.Around;
+import org.aspectj.lang.annotation.Aspect;
+import org.aspectj.lang.annotation.Pointcut;
+import org.aspectj.lang.reflect.MethodSignature;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.core.annotation.Order;
+import org.springframework.stereotype.Component;
+
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+* @author  作者 : 小布
+* @version 创建时间 : 2019年6月11日 下午3:57:27 
+* @explain 类说明 : 限制访问次数
+*/
+@Component
+@Order
+@Aspect
+public class LimitAspect {
+
+    private Map limitMap = new HashMap();
+    
+    
+    private static final Logger log = LoggerFactory.getLogger(LimitAspect.class);
+
+    @Pointcut("@annotation(limitKey)")
+    public void limit(LimitKey limitKey) {
+    }
+
+    @Around("limit(limitKey)")
+    public Object aroundLog(ProceedingJoinPoint joinpoint, LimitKey limitKey) throws Throwable {
+        MethodSignature methodSignature = (MethodSignature) joinpoint.getSignature();
+        int frequency = limitKey.frequency();
+        String methodName = limitKey.methodName();
+        String paramKey = limitKey.paramKey();
+        String url = limitKey.url();
+        //入参
+        String[] parameterNames = methodSignature.getParameterNames();
+        Object[] args = joinpoint.getArgs();
+        Object obj = null ;
+        
+        for(int i = 0 ; i < parameterNames.length;i++) {
+            if(parameterNames[i].equals(paramKey)) {
+                obj = args[i];
+                break;
+            }
+        }
+        
+        StringBuffer sb = new StringBuffer();
+        sb.append(url).append("/_").append(methodName).append("_").append(paramKey).append("_").append(obj).append("_key");
+        if(limitMap.get(sb.toString()) == null ) {
+             limitMap.put(sb.toString(),frequency-1);
+        } else {
+             int l = (int) limitMap.get(sb.toString());
+             if(l > 0){
+                 limitMap.put(sb.toString(), --l);
+             } else {
+            	 Map<String, Object> mp = new HashMap<String, Object>();
+             	 mp.put("msg", 50003);//接口超过请求次数
+                 return mp;
+             }
+        }
+        System.err.println("剩余次数:"+limitMap.get(sb.toString())+" 自定义key:"+sb.toString());
+        return joinpoint.proceed();
+    }
+
+}

+ 34 - 0
huimv-smart-apiservice/src/main/java/com/huimv/apiservice/limit/LimitKey.java

@@ -0,0 +1,34 @@
+package com.huimv.apiservice.limit;
+
+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  作者 : yinhao
+* @version 创建时间 : 2021年4月29日 下午3:54:07
+* @explain 类说明 : 限制访问次数
+*/
+@Target(ElementType.METHOD)
+@Retention(RetentionPolicy.RUNTIME)
+@Documented
+public @interface LimitKey {
+	
+	//方法名称
+	String methodName() default "";
+		
+	//访问次数
+	int frequency() default 10;
+	
+	//业务KEY
+	String paramKey() default "CDPathSta";
+	
+	//请求地址
+	String url() default "";
+	
+	//过期时间
+	long timeout() default 1000;
+		
+}

+ 45 - 0
huimv-smart-apiservice/src/main/java/com/huimv/apiservice/utils/ApiSignCreate.java

@@ -0,0 +1,45 @@
+//package com.huimv.apiservice.utils;
+//
+//
+//import org.apache.catalina.security.SecurityUtil;
+//
+//import javax.crypto.Cipher;
+//import java.security.PrivateKey;
+//import java.util.ArrayList;
+//import java.util.Collections;
+//import java.util.List;
+//import java.util.Map;
+//
+///**
+// * @Author yinhao
+// * @Date 2021/4/28 19:01
+// * @Description
+// */
+//public class ApiSignCreate {
+//
+//    public static String getSortedContent(Map<String, String> data) {
+//        StringBuffer content = new StringBuffer();
+//        List<String> keys = new ArrayList<String>(data.keySet());
+//        Collections.sort(keys);
+//        int index = 0;
+//        for (String key : keys) {
+//            String value = data.get(key);
+//            content.append((index == 0 ? "" : "&")).append(key).append("=").append(value);
+//            index++;
+//        }
+//        return content.toString();
+//    }
+//
+//    public static String EncryptByRSAPriKey(String content,String priKey) throws Exception {
+//        try {
+//            PrivateKey privateKey = SecurityUtil.getRSAPriKey(priKey);
+//            Cipher cipher = Cipher.getInstance(privateKey.getAlgorithm());
+//            cipher.init(Cipher.ENCRYPT_MODE, privateKey);
+//            cipher.update(content.getBytes(SecurityUtil.RSA_CHARSET));
+//            return SecurityUtil.encodeBase64(cipher.doFinal());
+//        } catch (Exception e) {
+//            e.printStackTrace();
+//            throw new Exception();
+//        }
+//    }
+//}

+ 12 - 0
huimv-smart-apiservice/src/main/java/com/huimv/apiservice/utils/ApiVerifyUtil.java

@@ -0,0 +1,12 @@
+package com.huimv.apiservice.utils;
+
+/**
+ * @Author yinhao
+ * @Date 2021/4/28 19:00
+ * @Description
+ */
+public class ApiVerifyUtil {
+
+
+
+}

+ 134 - 0
huimv-smart-apiservice/src/main/java/com/huimv/apiservice/utils/SimpleApiSignInterceptor.java

@@ -0,0 +1,134 @@
+//package com.huimv.apiservice.utils;
+//
+//import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;
+//import org.springframework.web.util.WebUtils;
+//
+//import javax.servlet.http.HttpServletRequest;
+//import javax.servlet.http.HttpServletResponse;
+//import java.io.IOException;
+//import java.io.StringReader;
+//import java.io.UnsupportedEncodingException;
+//import java.util.*;
+//import java.util.concurrent.ConcurrentHashMap;
+//
+///**
+// * Author: Kelin
+// * Date:  2018/5/16
+// * Description:
+// */
+//@SuppressWarnings("SuspiciousMethodCalls")
+//public class SimpleApiSignInterceptor extends HandlerInterceptorAdapter {
+//
+//    // 签名超时时长,默认时间为5分钟,ms
+//    private static final int SIGN_EXPIRED_TIME = 5 * 60 * 1000;
+//
+//    private static final String API_SIGN_KEY_CONFIG_PATH = "/mop/common/system/api_sign_key_mapping.properties";
+//
+//    private static final String SIGN_KEY = "sign";
+//
+//    private static final String TIMESTAMP_KEY = "timestamp";
+//
+//    private static final String ACCESS_KEY = "accessKey";
+//
+//    private static final String ACCESS_SECRET = "accessSecret";
+//
+//    private static Map<String, String> map = new ConcurrentHashMap<String, String>();
+//
+//
+//    static {
+//        // 从zk加载key映射到内存里面
+//        try {
+//            String data = ZKClient.get().getStringData(API_SIGN_KEY_CONFIG_PATH);
+//            Properties properties = new Properties();
+//            properties.load(new StringReader(data));
+//            for (Object key : properties.keySet()) {
+//                map.put(String.valueOf(key), properties.getProperty(String.valueOf(key)));
+//            }
+//        } catch (KeeperException e) {
+//            e.printStackTrace();
+//        } catch (InterruptedException e) {
+//            e.printStackTrace();
+//        } catch (IOException e) {
+//            e.printStackTrace();
+//        }
+//
+//    }
+//
+//    @Override
+//    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
+//
+//        Map<String, Object> result = new HashMap<String, Object>();
+//        String timestamp = request.getParameter(TIMESTAMP_KEY);
+//        String accessKey = request.getParameter(ACCESS_KEY);
+//        String accessSecret = map.get(accessKey);
+//
+//        if (!org.apache.commons.lang.StringUtils.isNumeric(timestamp)) {
+//            result.put("code", 1000);
+//            result.put("msg", "请求时间戳不合法");
+//            WebUtils.writeJsonByObj(result, response, request);
+//            return false;
+//        }
+//
+//        // 检查KEY是否合理
+//        if (StringUtils.isEmpty(accessKey) || StringUtils.isEmpty(accessSecret)) {
+//            result.put("code", 1001);
+//            result.put("msg", "加密KEY不合法");
+//            WebUtils.writeJsonByObj(result, response, request);
+//            return false;
+//        }
+//        Long ts = Long.valueOf(timestamp);
+//        // 禁止超时签名
+//        if (System.currentTimeMillis() - ts > SIGN_EXPIRED_TIME) {
+//            result.put("code", 1002);
+//            result.put("msg", "请求超时");
+//            WebUtils.writeJsonByObj(result, response, request);
+//            return false;
+//        }
+//
+//        if (!verificationSign(request, accessKey, accessSecret)) {
+//            result.put("code", 1003);
+//            result.put("msg", "签名错误");
+//            WebUtils.writeJsonByObj(result, response, request);
+//            return false;
+//        }
+//        return true;
+//    }
+//
+//    private boolean verificationSign(HttpServletRequest request, String accessKey, String accessSecret) throws UnsupportedEncodingException {
+//        Enumeration<?> pNames = request.getParameterNames();
+//        Map<String, Object> params = new HashMap<String, Object>();
+//        while (pNames.hasMoreElements()) {
+//            String pName = (String) pNames.nextElement();
+//            if (SIGN_KEY.equals(pName)) continue;
+//            Object pValue = request.getParameter(pName);
+//            params.put(pName, pValue);
+//        }
+//        String originSign = request.getParameter(SIGN_KEY);
+//        String sign = createSign(params, accessSecret);
+//        return sign.equals(originSign);
+//    }
+//
+//    private String createSign(Map<String, Object> params, String accessSecret) throws UnsupportedEncodingException {
+//        Set<String> keysSet = params.keySet();
+//        Object[] keys = keysSet.toArray();
+//        Arrays.sort(keys);
+//        StringBuilder temp = new StringBuilder();
+//        boolean first = true;
+//        for (Object key : keys) {
+//            if (first) {
+//                first = false;
+//            } else {
+//                temp.append("&");
+//            }
+//            temp.append(key).append("=");
+//            Object value = params.get(key);
+//            String valueString = "";
+//            if (null != value) {
+//                valueString = String.valueOf(value);
+//            }
+//            temp.append(valueString);
+//        }
+//        temp.append("&").append(ACCESS_SECRET).append("=").append(accessSecret);
+//        return MD5Util.MD52(temp.toString()).toUpperCase();
+//    }
+//}

+ 19 - 1
huimv-smart-common/pom.xml

@@ -39,6 +39,10 @@
             <artifactId>commons-lang</artifactId>
             <version>2.6</version>
         </dependency>
+        <dependency>
+            <groupId>org.apache.commons</groupId>
+            <artifactId>commons-lang3</artifactId>
+        </dependency>
 
         <!--mysql驱动-->
         <dependency>
@@ -51,7 +55,7 @@
         <dependency>
             <groupId>com.alibaba</groupId>
             <artifactId>druid-spring-boot-starter</artifactId>
-            <version>1.1.23</version>
+            <version>1.2.5</version>
         </dependency>
 
         <!--servlet-api-->
@@ -125,6 +129,20 @@
             <artifactId>gson</artifactId>
         </dependency>
 
+        <!--hutool-->
+        <dependency>
+            <groupId>cn.hutool</groupId>
+            <artifactId>hutool-all</artifactId>
+            <version>LATEST</version>
+        </dependency>
+
+        <!--google.guava-->
+        <dependency>
+            <groupId>com.google.guava</groupId>
+            <artifactId>guava</artifactId>
+            <version>29.0-jre</version>
+        </dependency>
+
         <!--<dependency>-->
             <!--<groupId>com.alibaba.cloud</groupId>-->
             <!--<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>-->

+ 15 - 0
huimv-smart-common/src/main/java/com/huimv/common/exception/LimitAccessException.java

@@ -0,0 +1,15 @@
+package com.huimv.common.exception;
+
+/**
+ * 自定义限流异常
+ *
+ * @author lichong
+ */
+public class LimitAccessException extends RuntimeException {
+
+    private static final long serialVersionUID = -3608667856397125671L;
+
+    public LimitAccessException(String message) {
+        super(message);
+    }
+}

+ 6 - 0
huimv-smart-common/src/main/java/com/huimv/common/exception/RRExceptionHandler.java

@@ -56,6 +56,12 @@ public class RRExceptionHandler {
 		return R.error("没有权限,请联系管理员授权");
 	}
 
+	@ExceptionHandler(value = LimitAccessException.class)
+	public R handleLimitAccessException(LimitAccessException e) {
+		logger.error("LimitAccessException", e);
+		return  R.error(429,e.getMessage());
+	}
+
 	@ExceptionHandler(Exception.class)
 	public R handleException(Exception e){
 		logger.error(e.getMessage(), e);

+ 21 - 0
huimv-smart-common/src/main/java/com/huimv/common/utils/HttpContextUtil.java

@@ -0,0 +1,21 @@
+package com.huimv.common.utils;
+
+import org.springframework.web.context.request.RequestContextHolder;
+import org.springframework.web.context.request.ServletRequestAttributes;
+
+import javax.servlet.http.HttpServletRequest;
+import java.util.Objects;
+
+/**
+ * @author lichong
+ * 在除了controller以外的地方想要获取到 httpServletRequest 可以通过 RequestContextHolder 获取,
+ */
+public class HttpContextUtil {
+
+	private HttpContextUtil(){
+
+	}
+	public static HttpServletRequest getHttpServletRequest() {
+		return ((ServletRequestAttributes) Objects.requireNonNull(RequestContextHolder.getRequestAttributes())).getRequest();
+	}
+}

+ 66 - 0
huimv-smart-common/src/main/java/com/huimv/common/utils/IPUtil.java

@@ -0,0 +1,66 @@
+package com.huimv.common.utils;
+
+import javax.servlet.http.HttpServletRequest;
+import static cn.hutool.core.net.NetUtil.isInnerIP;
+/**
+ * @author lichong
+ */
+public class IPUtil {
+
+	private static final String UNKNOWN = "unknown";
+
+	protected IPUtil(){
+
+	}
+
+	/**
+	 * 获取 IP地址
+	 * 使用 Nginx等反向代理软件, 则不能通过 request.getRemoteAddr()获取 IP地址
+	 * 如果使用了多级反向代理的话,X-Forwarded-For的值并不止一个,而是一串IP地址,
+	 * X-Forwarded-For中第一个非 unknown的有效IP字符串,则为真实IP地址
+	 *
+	 * ip地址能伪造,不能百分之百确定真实ip
+	 */
+	public static String getIpAddr(HttpServletRequest request) {
+		// 获取客户端ip地址
+		String clientIp = request.getHeader("x-forwarded-for");
+		if (clientIp == null || clientIp.length() == 0 || "unknown".equalsIgnoreCase(clientIp)) {
+			clientIp = request.getHeader("Proxy-Client-IP");
+		}
+		if (clientIp == null || clientIp.length() == 0 || "unknown".equalsIgnoreCase(clientIp)) {
+			clientIp = request.getHeader("WL-Proxy-Client-IP");
+		}
+		if (clientIp == null || clientIp.length() == 0 || "unknown".equalsIgnoreCase(clientIp)) {
+			clientIp = request.getRemoteAddr();
+		}
+		/*
+		 * 对于获取到多ip的情况下,找到公网ip.
+		 */
+		String sIP = null;
+		if (clientIp != null && !clientIp.contains("unknown") && clientIp.indexOf(",") > 0) {
+			String[] ipsz = clientIp.split(",");
+			for (String anIpsz : ipsz) {
+				if (!isInnerIP(anIpsz.trim())) {
+					sIP = anIpsz.trim();
+					break;
+				}
+			}
+			/*
+			 * 如果多ip都是内网ip,则取第一个ip.
+			 */
+			if (null == sIP) {
+				sIP = ipsz[0].trim();
+			}
+			clientIp = sIP;
+		}
+		if (clientIp != null && clientIp.contains("unknown")){
+			clientIp =clientIp.replaceAll("unknown,", "");
+			clientIp = clientIp.trim();
+		}
+		if ("".equals(clientIp) || null == clientIp){
+			clientIp = "127.0.0.1";
+		}
+		return clientIp;
+	}
+
+}

+ 611 - 0
huimv-smart-common/src/main/java/com/huimv/common/utils/RedisUtil.java

@@ -0,0 +1,611 @@
+package com.huimv.common.utils;
+
+import java.util.*;
+import java.util.concurrent.TimeUnit;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.data.redis.core.RedisTemplate;
+import org.springframework.stereotype.Component;
+import org.springframework.util.CollectionUtils;
+
+
+/**
+ * Redis工具类
+ */
+
+@Component
+public final class RedisUtil {
+
+    @Autowired
+    private RedisTemplate<String, Object> redisTemplate;
+    // =============================common============================
+
+    /**
+     * 指定缓存失效时间
+     *
+     * @param key  键
+     * @param time 时间(秒)
+     * @return
+     */
+    public boolean expire(String key, long time) {
+        try {
+            if (time > 0) {
+                redisTemplate.expire(key, time, TimeUnit.SECONDS);
+            }
+            return true;
+        } catch (Exception e) {
+            e.printStackTrace();
+            return false;
+        }
+    }
+
+    /**
+     * 指定缓存失效时间
+     *
+     * @param key  键
+     * @param time 时间(毫秒)
+     * @return
+     */
+    public boolean expireByMillisecond(String key, long time) {
+        try {
+            if (time > 0) {
+                redisTemplate.expire(key, time, TimeUnit.MILLISECONDS);
+            }
+            return true;
+        } catch (Exception e) {
+            e.printStackTrace();
+            return false;
+        }
+    }
+
+    /**
+     * 根据key 获取过期时间
+     *
+     * @param key 键 不能为null
+     * @return 时间(秒) 返回0代表为永久有效
+     */
+    public long getExpire(String key) {
+        return redisTemplate.getExpire(key, TimeUnit.SECONDS);
+    }
+
+    /**
+     * 判断key是否存在
+     *
+     * @param key 键
+     * @return true 存在 false不存在
+     */
+    public boolean hasKey(String key) {
+        try {
+            return redisTemplate.hasKey(key);
+        } catch (Exception e) {
+            e.printStackTrace();
+            return false;
+        }
+    }
+
+    /**
+     * 删除缓存
+     *
+     * @param key 可以传一个值 或多个
+     */
+    @SuppressWarnings("unchecked")
+    public void del(String... key) {
+        if (key != null && key.length > 0) {
+            if (key.length == 1) {
+                redisTemplate.delete(key[0]);
+            } else {
+                List<String> keys = new ArrayList<>();
+                Collections.addAll(keys, key);
+                redisTemplate.delete(keys);
+            }
+        }
+    }
+    // ============================String=============================
+
+    /**
+     * 普通缓存获取
+     *
+     * @param key 键
+     * @return 值
+     */
+    public Object get(String key) {
+        return key == null ? null : redisTemplate.opsForValue().get(key);
+    }
+
+    /**
+     * 普通缓存放入
+     *
+     * @param key   键
+     * @param value 值
+     * @return true成功 false失败
+     */
+    public boolean set(String key, Object value) {
+        try {
+            redisTemplate.opsForValue().set(key, value);
+            return true;
+        } catch (Exception e) {
+            e.printStackTrace();
+            return false;
+        }
+    }
+
+    /**
+     * 普通缓存放入并设置时间
+     *
+     * @param key   键
+     * @param value 值
+     * @param time  时间(秒) time要大于0 如果time小于等于0 将设置无限期
+     * @return true成功 false 失败
+     */
+    public boolean set(String key, Object value, long time) {
+        try {
+            if (time > 0) {
+                redisTemplate.opsForValue().set(key, value, time, TimeUnit.SECONDS);
+            } else {
+                set(key, value);
+            }
+            return true;
+        } catch (Exception e) {
+            e.printStackTrace();
+            return false;
+        }
+    }
+
+    /**
+     * 普通缓存放入并设置时间
+     *
+     * @param key   键
+     * @param value 值
+     * @param time  时间(秒) time要大于0 如果time小于等于0 将设置无限期
+     * @return true成功 false 失败
+     */
+    public boolean setbyMillisecond(String key, Object value, long time) {
+        try {
+            if (time > 0) {
+                redisTemplate.opsForValue().set(key, value, time, TimeUnit.MILLISECONDS);
+            } else {
+                set(key, value);
+            }
+            return true;
+        } catch (Exception e) {
+            e.printStackTrace();
+            return false;
+        }
+    }
+
+
+    /**
+     * 递增
+     *
+     * @param key   键
+     * @param delta 要增加几(大于0)
+     * @return
+     */
+    public long incr(String key, long delta) {
+        if (delta < 0) {
+            throw new RuntimeException("递增因子必须大于0");
+        }
+        return redisTemplate.opsForValue().increment(key, delta);
+    }
+
+    /**
+     * 递减
+     *
+     * @param key   键
+     * @param delta 要减少几(小于0)
+     * @return
+     */
+    public long decr(String key, long delta) {
+        if (delta < 0) {
+            throw new RuntimeException("递减因子必须大于0");
+        }
+        return redisTemplate.opsForValue().increment(key, -delta);
+    }
+    // ================================Map=================================
+
+    /**
+     * HashGet
+     *
+     * @param key  键 不能为null
+     * @param item 项 不能为null
+     * @return 值
+     */
+    public Object hget(String key, String item) {
+        return redisTemplate.opsForHash().get(key, item);
+    }
+
+    /**
+     * 获取hashKey对应的所有键值
+     *
+     * @param key 键
+     * @return 对应的多个键值
+     */
+    public Map<Object, Object> hmget(String key) {
+        return redisTemplate.opsForHash().entries(key);
+    }
+
+    /**
+     * HashSet
+     *
+     * @param key 键
+     * @param map 对应多个键值
+     * @return true 成功 false 失败
+     */
+    public boolean hmset(String key, Map<String, Object> map) {
+        try {
+            redisTemplate.opsForHash().putAll(key, map);
+            return true;
+        } catch (Exception e) {
+            e.printStackTrace();
+            return false;
+        }
+    }
+
+    /**
+     * HashSet 并设置时间
+     *
+     * @param key  键
+     * @param map  对应多个键值
+     * @param time 时间(秒)
+     * @return true成功 false失败
+     */
+    public boolean hmset(String key, Map<String, Object> map, long time) {
+        try {
+            redisTemplate.opsForHash().putAll(key, map);
+            if (time > 0) {
+                expire(key, time);
+            }
+            return true;
+        } catch (Exception e) {
+            e.printStackTrace();
+            return false;
+        }
+    }
+
+    /**
+     * 向一张hash表中放入数据,如果不存在将创建
+     *
+     * @param key   键
+     * @param item  项
+     * @param value 值
+     * @return true 成功 false失败
+     */
+    public boolean hset(String key, String item, Object value) {
+        try {
+            redisTemplate.opsForHash().put(key, item, value);
+            return true;
+        } catch (Exception e) {
+            e.printStackTrace();
+            return false;
+        }
+    }
+
+    /**
+     * 向一张hash表中放入数据,如果不存在将创建
+     *
+     * @param key   键
+     * @param item  项
+     * @param value 值
+     * @param time  时间(秒) 注意:如果已存在的hash表有时间,这里将会替换原有的时间
+     * @return true 成功 false失败
+     */
+    public boolean hset(String key, String item, Object value, long time) {
+        try {
+            redisTemplate.opsForHash().put(key, item, value);
+            if (time > 0) {
+                expire(key, time);
+            }
+            return true;
+        } catch (Exception e) {
+            e.printStackTrace();
+            return false;
+        }
+    }
+
+    /**
+     * 删除hash表中的值
+     *
+     * @param key  键 不能为null
+     * @param item 项 可以使多个 不能为null
+     */
+    public void hdel(String key, Object... item) {
+        redisTemplate.opsForHash().delete(key, item);
+    }
+
+    /**
+     * 判断hash表中是否有该项的值
+     *
+     * @param key  键 不能为null
+     * @param item 项 不能为null
+     * @return true 存在 false不存在
+     */
+    public boolean hHasKey(String key, String item) {
+        return redisTemplate.opsForHash().hasKey(key, item);
+    }
+
+    /**
+     * hash递增 如果不存在,就会创建一个 并把新增后的值返回
+     *
+     * @param key  键
+     * @param item 项
+     * @param by   要增加几(大于0)
+     * @return
+     */
+    public double hincr(String key, String item, double by) {
+        return redisTemplate.opsForHash().increment(key, item, by);
+    }
+
+    /**
+     * hash递减
+     *
+     * @param key  键
+     * @param item 项
+     * @param by   要减少记(小于0)
+     * @return
+     */
+    public double hdecr(String key, String item, double by) {
+        return redisTemplate.opsForHash().increment(key, item, -by);
+    }
+    // ============================set=============================
+
+    /**
+     * 根据key获取Set中的所有值
+     *
+     * @param key 键
+     * @return
+     */
+    public Set<Object> sGet(String key) {
+        try {
+            return redisTemplate.opsForSet().members(key);
+        } catch (Exception e) {
+            e.printStackTrace();
+            return null;
+        }
+    }
+
+    /**
+     * 根据value从一个set中查询,是否存在
+     *
+     * @param key   键
+     * @param value 值
+     * @return true 存在 false不存在
+     */
+    public boolean sHasKey(String key, Object value) {
+        try {
+            return redisTemplate.opsForSet().isMember(key, value);
+        } catch (Exception e) {
+            e.printStackTrace();
+            return false;
+        }
+    }
+
+    /**
+     * 将数据放入set缓存
+     *
+     * @param key    键
+     * @param values 值 可以是多个
+     * @return 成功个数
+     */
+    public long sSet(String key, Object... values) {
+        try {
+            return redisTemplate.opsForSet().add(key, values);
+        } catch (Exception e) {
+            e.printStackTrace();
+            return 0;
+        }
+    }
+
+    /**
+     * 将set数据放入缓存
+     *
+     * @param key    键
+     * @param time   时间(秒)
+     * @param values 值 可以是多个
+     * @return 成功个数
+     */
+    public long sSetAndTime(String key, long time, Object... values) {
+        try {
+            Long count = redisTemplate.opsForSet().add(key, values);
+            if (time > 0) {
+                expire(key, time);
+            }
+            return count;
+        } catch (Exception e) {
+            e.printStackTrace();
+            return 0;
+        }
+    }
+
+    /**
+     * 获取set缓存的长度
+     *
+     * @param key 键
+     * @return
+     */
+    public long sGetSetSize(String key) {
+        try {
+            return redisTemplate.opsForSet().size(key);
+        } catch (Exception e) {
+            e.printStackTrace();
+            return 0;
+        }
+    }
+
+    /**
+     * 移除值为value的
+     *
+     * @param key    键
+     * @param values 值 可以是多个
+     * @return 移除的个数
+     */
+    public long setRemove(String key, Object... values) {
+        try {
+            Long count = redisTemplate.opsForSet().remove(key, values);
+            return count;
+        } catch (Exception e) {
+            e.printStackTrace();
+            return 0;
+        }
+    }
+    // ===============================list=================================
+
+    /**
+     * 获取list缓存的内容
+     *
+     * @param key   键
+     * @param start 开始
+     * @param end   结束 0 到 -1代表所有值
+     * @return
+     */
+    public List<Object> lGet(String key, long start, long end) {
+        try {
+            return redisTemplate.opsForList().range(key, start, end);
+        } catch (Exception e) {
+            e.printStackTrace();
+            return null;
+        }
+    }
+
+    /**
+     * 获取list缓存的长度
+     *
+     * @param key 键
+     * @return
+     */
+    public long lGetListSize(String key) {
+        try {
+            return redisTemplate.opsForList().size(key);
+        } catch (Exception e) {
+            e.printStackTrace();
+            return 0;
+        }
+    }
+
+    /**
+     * 通过索引 获取list中的值
+     *
+     * @param key   键
+     * @param index 索引 index>=0时, 0 表头,1 第二个元素,依次类推;index<0时,-1,表尾,-2倒数第二个元素,依次类推
+     * @return
+     */
+    public Object lGetIndex(String key, long index) {
+        try {
+            return redisTemplate.opsForList().index(key, index);
+        } catch (Exception e) {
+            e.printStackTrace();
+            return null;
+        }
+    }
+
+    /**
+     * 将list放入缓存
+     *
+     * @param key   键
+     * @param value 值
+     * @return
+     */
+    public boolean lSet(String key, Object value) {
+        try {
+            redisTemplate.opsForList().rightPush(key, value);
+            return true;
+        } catch (Exception e) {
+            e.printStackTrace();
+            return false;
+        }
+    }
+
+    /**
+     * 将list放入缓存
+     *
+     * @param key   键
+     * @param value 值
+     * @param time  时间(秒)
+     * @return
+     */
+    public boolean lSet(String key, Object value, long time) {
+        try {
+            redisTemplate.opsForList().rightPush(key, value);
+            if (time > 0) {
+                expire(key, time);
+            }
+            return true;
+        } catch (Exception e) {
+            e.printStackTrace();
+            return false;
+        }
+    }
+
+    /**
+     * 将list放入缓存
+     *
+     * @param key   键
+     * @param value 值
+     * @return
+     */
+    public boolean lSet(String key, List<Object> value) {
+        try {
+            redisTemplate.opsForList().rightPushAll(key, value);
+            return true;
+        } catch (Exception e) {
+            e.printStackTrace();
+            return false;
+        }
+    }
+
+    /**
+     * 将list放入缓存
+     *
+     * @param key   键
+     * @param value 值
+     * @param time  时间(秒)
+     * @return
+     */
+    public boolean lSet(String key, List<Object> value, long time) {
+        try {
+            redisTemplate.opsForList().rightPushAll(key, value);
+            if (time > 0) {
+                expire(key, time);
+            }
+            return true;
+        } catch (Exception e) {
+            e.printStackTrace();
+            return false;
+        }
+    }
+
+    /**
+     * 根据索引修改list中的某条数据
+     *
+     * @param key   键
+     * @param index 索引
+     * @param value 值
+     * @return
+     */
+    public boolean lUpdateIndex(String key, long index, Object value) {
+        try {
+            redisTemplate.opsForList().set(key, index, value);
+            return true;
+        } catch (Exception e) {
+            e.printStackTrace();
+            return false;
+        }
+    }
+
+    /**
+     * 移除N个值为value
+     *
+     * @param key   键
+     * @param count 移除多少个
+     * @param value 值
+     * @return 移除的个数
+     */
+    public long lRemove(String key, long count, Object value) {
+        try {
+            Long remove = redisTemplate.opsForList().remove(key, count, value);
+            return remove;
+        } catch (Exception e) {
+            e.printStackTrace();
+            return 0;
+        }
+    }
+}

+ 1 - 1
huimv-smart-gateway/src/main/resources/application.yml

@@ -20,7 +20,7 @@ spring:
       routes:
         # renren-fast后台管理系统的路由(低优先级的放在下面)
         - id: admin_route
-          uri: http://192.168.1.54:9500
+          uri: http://192.168.1.57:9500
           predicates:
             - Path=/api/**
           filters:

+ 25 - 0
huimv-smart-management/src/main/java/com/huimv/management/Abc.java

@@ -0,0 +1,25 @@
+package com.huimv.management;
+
+import cn.hutool.core.date.DateTime;
+import cn.hutool.core.date.DateUnit;
+import cn.hutool.core.date.DateUtil;
+
+
+/**
+ * @Author yinhao
+ * @Date 2021/4/29 16:58
+ * @Description
+ */
+public class Abc {
+
+    public static void main(String[] args) {
+        System.out.println(DateUtil.date());
+        DateTime dateTime = DateUtil.offsetDay(DateUtil.date(), 1);
+        System.out.println(dateTime);
+        DateTime dateTime1 = DateUtil.beginOfDay(dateTime);
+        System.out.println(dateTime1);
+        long between = DateUtil.between(DateUtil.date(), dateTime1, DateUnit.SECOND);
+        System.out.println(between);
+
+    }
+}

+ 46 - 0
huimv-smart-management/src/main/java/com/huimv/management/config/RedisConfigure.java

@@ -0,0 +1,46 @@
+package com.huimv.management.config;
+
+import com.fasterxml.jackson.annotation.JsonAutoDetect;
+import com.fasterxml.jackson.annotation.PropertyAccessor;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.data.redis.connection.RedisConnectionFactory;
+import org.springframework.data.redis.core.RedisOperations;
+import org.springframework.data.redis.core.RedisTemplate;
+import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
+import org.springframework.data.redis.serializer.StringRedisSerializer;
+
+/**
+ * @author yinhao
+ */
+@Configuration
+public class RedisConfigure {
+
+    @Bean
+    @ConditionalOnClass(RedisOperations.class)
+    public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory factory) {
+        RedisTemplate<String, Object> template = new RedisTemplate<>();
+        template.setConnectionFactory(factory);
+
+        Jackson2JsonRedisSerializer<Object> jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer<>(Object.class);
+        ObjectMapper mapper = new ObjectMapper();
+        mapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
+        mapper.activateDefaultTyping(mapper.getPolymorphicTypeValidator(), ObjectMapper.DefaultTyping.NON_FINAL);
+        jackson2JsonRedisSerializer.setObjectMapper(mapper);
+
+        StringRedisSerializer stringRedisSerializer = new StringRedisSerializer();
+        // key采用 String的序列化方式
+        template.setKeySerializer(stringRedisSerializer);
+        // hash的 key也采用 String的序列化方式
+        template.setHashKeySerializer(stringRedisSerializer);
+        // value序列化方式采用 jackson
+        template.setValueSerializer(jackson2JsonRedisSerializer);
+        // hash的 value序列化方式采用 jackson
+        template.setHashValueSerializer(jackson2JsonRedisSerializer);
+        template.afterPropertiesSet();
+
+        return template;
+    }
+}

+ 88 - 0
huimv-smart-management/src/main/java/com/huimv/management/controller/TestController.java

@@ -0,0 +1,88 @@
+package com.huimv.management.controller;
+
+import java.util.Arrays;
+import java.util.Map;
+
+import com.huimv.management.limit.annotation.Limit;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.RestController;
+
+import com.huimv.management.entity.TestEntity;
+import com.huimv.management.service.TestService;
+import com.huimv.common.utils.PageUtils;
+import com.huimv.common.utils.R;
+
+
+/**
+ * @author yinhao
+ * @email yinhao@163.com
+ * @date 2021-04-28 19:33:24
+ */
+@RestController
+@RequestMapping("/test")
+public class TestController {
+    @Autowired
+    private TestService testService;
+
+    /**
+     * 列表
+     */
+    @Limit(key = "test_list",name = "test/list",prefix = "management")
+    @RequestMapping("/list")
+    //@RequiresPermissions("management:test:list")
+    public R list(@RequestParam Map<String, Object> params) {
+        PageUtils page = testService.queryPage(params);
+
+        return R.ok().put("page", page);
+    }
+
+
+    /**
+     * 信息
+     */
+    @RequestMapping("/info/{name}")
+    //@RequiresPermissions("management:test:info")
+    public R info(@PathVariable("name") String name) {
+        TestEntity test = testService.getById(name);
+
+        return R.ok().put("test", test);
+    }
+
+    /**
+     * 保存
+     */
+    @RequestMapping("/save")
+    //@RequiresPermissions("management:test:save")
+    public R save(@RequestBody TestEntity test) {
+        testService.save(test);
+
+        return R.ok();
+    }
+
+    /**
+     * 修改
+     */
+    @RequestMapping("/update")
+    //@RequiresPermissions("management:test:update")
+    public R update(@RequestBody TestEntity test) {
+        testService.updateById(test);
+
+        return R.ok();
+    }
+
+    /**
+     * 删除
+     */
+    @RequestMapping("/delete")
+    //@RequiresPermissions("management:test:delete")
+    public R delete(@RequestBody String[] names) {
+        testService.removeByIds(Arrays.asList(names));
+
+        return R.ok();
+    }
+
+}

+ 17 - 0
huimv-smart-management/src/main/java/com/huimv/management/dao/TestDao.java

@@ -0,0 +1,17 @@
+package com.huimv.management.dao;
+
+import com.huimv.management.entity.TestEntity;
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import org.apache.ibatis.annotations.Mapper;
+
+/**
+ * 
+ * 
+ * @author yinhao
+ * @email yinhao@163.com
+ * @date 2021-04-28 19:33:24
+ */
+@Mapper
+public interface TestDao extends BaseMapper<TestEntity> {
+	
+}

+ 36 - 0
huimv-smart-management/src/main/java/com/huimv/management/entity/TestEntity.java

@@ -0,0 +1,36 @@
+package com.huimv.management.entity;
+
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+
+import java.io.Serializable;
+import java.util.Date;
+import lombok.Data;
+
+/**
+ * 
+ * 
+ * @author yinhao
+ * @email yinhao@163.com
+ * @date 2021-04-28 19:33:24
+ */
+@Data
+@TableName("mgt_test")
+public class TestEntity implements Serializable {
+	private static final long serialVersionUID = 1L;
+
+	/**
+	 * 
+	 */
+	@TableId
+	private String name;
+	/**
+	 * 
+	 */
+	private String address;
+	/**
+	 * 
+	 */
+	private Integer age;
+
+}

+ 51 - 0
huimv-smart-management/src/main/java/com/huimv/management/limit/annotation/Limit.java

@@ -0,0 +1,51 @@
+package com.huimv.management.limit.annotation;
+
+import com.huimv.management.limit.enums.LimitType;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * <p>
+ * 业务用注解
+ * </p>
+ * 示例: @Limit(key = "test_list",name = "test/list",prefix = "management")
+ * @author huimv
+ * @since 2021/4/29
+ */
+@Target(ElementType.METHOD)
+@Retention(RetentionPolicy.RUNTIME)
+public @interface Limit {
+
+    /**
+     * 资源名称,用于描述接口功能
+     */
+    String name() default "";
+
+    /**
+     * 资源 key
+     */
+    String key() default "";
+
+    /**
+     * key prefix
+     */
+    String prefix() default "";
+
+    /**
+     * 时间范围,单位秒
+     */
+    long period() default 60 * 60 * 24L;
+
+    /**
+     * 限制访问次数
+     */
+    long count() default 3L;
+
+    /**
+     * 限制类型
+     */
+    LimitType limitType() default LimitType.IP;
+}

+ 44 - 0
huimv-smart-management/src/main/java/com/huimv/management/limit/aspect/AspectSupport.java

@@ -0,0 +1,44 @@
+package com.huimv.management.limit.aspect;
+
+import org.aspectj.lang.ProceedingJoinPoint;
+import org.aspectj.lang.reflect.MethodSignature;
+
+import java.lang.reflect.Method;
+
+/**
+ * @author yinhao
+ * 反射获取到当前joinpoint的方法
+ */
+public abstract class AspectSupport {
+
+    Method resolveMethod(ProceedingJoinPoint point) {
+        MethodSignature signature = (MethodSignature)point.getSignature();
+        Class<?> targetClass = point.getTarget().getClass();
+
+        Method method = getDeclaredMethod(targetClass, signature.getName(),
+                signature.getMethod().getParameterTypes());
+        if (method == null) {
+            throw new IllegalStateException("无法解析目标方法: " + signature.getMethod().getName());
+        }
+        return method;
+    }
+
+    /**
+     * 反射获取有参方法
+     * @param clazz clazz
+     * @param name name
+     * @param parameterTypes parameterTypes
+     * @return Method
+     */
+    private Method getDeclaredMethod(Class<?> clazz, String name, Class<?>... parameterTypes) {
+        try {
+            return clazz.getDeclaredMethod(name, parameterTypes);
+        } catch (NoSuchMethodException e) {
+            Class<?> superClass = clazz.getSuperclass();
+            if (superClass != null) {
+                return getDeclaredMethod(superClass, name, parameterTypes);
+            }
+        }
+        return null;
+    }
+}

+ 110 - 0
huimv-smart-management/src/main/java/com/huimv/management/limit/aspect/LimitAspect.java

@@ -0,0 +1,110 @@
+package com.huimv.management.limit.aspect;
+
+import cn.hutool.core.date.DateTime;
+import cn.hutool.core.date.DateUnit;
+import cn.hutool.core.date.DateUtil;
+import com.google.common.collect.ImmutableList;
+import com.huimv.common.exception.LimitAccessException;
+import com.huimv.common.utils.HttpContextUtil;
+import com.huimv.common.utils.IPUtil;
+import com.huimv.management.limit.enums.LimitType;
+import com.huimv.management.limit.annotation.Limit;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.lang3.StringUtils;
+import org.aspectj.lang.ProceedingJoinPoint;
+import org.aspectj.lang.annotation.Around;
+import org.aspectj.lang.annotation.Aspect;
+import org.aspectj.lang.annotation.Pointcut;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.data.redis.core.RedisTemplate;
+import org.springframework.data.redis.core.script.DefaultRedisScript;
+import org.springframework.data.redis.core.script.RedisScript;
+import org.springframework.stereotype.Component;
+
+import javax.servlet.http.HttpServletRequest;
+import java.lang.reflect.Method;
+
+
+
+/**
+ * 接口限流
+ *
+ * @author yinhao
+ */
+@Slf4j
+@Aspect
+@Component
+public class LimitAspect extends AspectSupport {
+
+    @Autowired
+    private RedisTemplate<String, Object> redisTemplate;
+
+    @Pointcut("@annotation(com.huimv.management.limit.annotation.Limit)")
+    public void pointcut() {
+    }
+
+    @Around("pointcut()")
+    public Object around(ProceedingJoinPoint point) throws Throwable {
+        // 获取到 HttpServletRequest
+        HttpServletRequest request = HttpContextUtil.getHttpServletRequest();
+        Method method = resolveMethod(point);
+        // 获取到注解
+        Limit limitAnnotation = method.getAnnotation(Limit.class);
+        // CUSTOMER 还是 IP
+        LimitType limitType = limitAnnotation.limitType();
+        // 在 redis 中需要使用这个 name 拼接 key
+        String name = limitAnnotation.name();
+        String key;
+        // 获取客户端ip
+        String ip = IPUtil.getIpAddr(request);
+
+        //long limitPeriod = limitAnnotation.period();
+        //修改过期时间为下一天00:00
+        DateTime current = DateUtil.date();
+        DateTime tomorrow = DateUtil.beginOfDay(DateUtil.offsetDay(current, 1));
+        long expire = DateUtil.between(current, tomorrow, DateUnit.SECOND);
+
+
+        long limitCount = limitAnnotation.count();
+        switch (limitType) {
+            case IP:
+                key = limitAnnotation.key() + ip;
+                break;
+            case CUSTOMER:
+                key = limitAnnotation.key();
+                break;
+            default:
+                key = StringUtils.upperCase(method.getName());
+        }
+        // redis 通过key来区分唯一
+        ImmutableList<String> keys = ImmutableList.of(StringUtils.join(limitAnnotation.prefix() + "_", key));
+        String luaScript = buildLuaScript();
+        RedisScript<Long> redisScript = new DefaultRedisScript<>(luaScript, Long.class);
+        Long count = redisTemplate.execute(redisScript, keys, limitCount, expire);
+        log.info("IP:{} 第 {} 次访问key为 {},描述为 [{}] 的接口", ip, count, keys, name);
+        if (count != null && count.intValue() <= limitCount) {
+            return point.proceed();
+        } else {
+            throw new LimitAccessException("当天可访问次数已达上限!");
+        }
+    }
+
+    /**
+     * 限流脚本 参考redis文档  http://doc.redisfans.com/script/eval.html
+     * 调用的时候不超过阈值,则直接返回并执行计算器自加。
+     *
+     * @return lua脚本
+     */
+    private String buildLuaScript() {
+        return "local c" +
+                "\n c = redis.call('get',KEYS[1])" +
+                "\n if c and tonumber(c) > tonumber(ARGV[1]) then" +
+                "\n return c;" +
+                "\n end" +
+                "\n c = redis.call('incr',KEYS[1])" +
+                "\n if tonumber(c) == 1 then" +
+                "\n redis.call('expire',KEYS[1],ARGV[2])" +
+                "\n end" +
+                "\n return c;";
+    }
+}

+ 19 - 0
huimv-smart-management/src/main/java/com/huimv/management/limit/enums/LimitType.java

@@ -0,0 +1,19 @@
+package com.huimv.management.limit.enums;
+
+/**
+ * <p>
+ * Limit类型枚举
+ * </p>
+ * @author yinhao
+ * @since 2021/4/29 17:22
+ */
+public enum LimitType {
+    /**
+     * 用户名
+     */
+    CUSTOMER,
+    /**
+     *  根据 IP地址限制
+     */
+    IP
+}

Plik diff jest za duży
+ 89 - 0
huimv-smart-management/src/main/java/com/huimv/management/rsa/ClientController.java


+ 62 - 0
huimv-smart-management/src/main/java/com/huimv/management/rsa/GeneratorRSAKey.java

@@ -0,0 +1,62 @@
+package com.huimv.management.rsa;
+
+import java.security.KeyPair;
+import java.security.KeyPairGenerator;
+import java.security.NoSuchAlgorithmException;
+import java.security.interfaces.RSAPrivateKey;
+import java.security.interfaces.RSAPublicKey;
+import java.util.Base64;
+
+/**
+ * @description 生成RSA公/私钥对
+ * 
+ * @author admin
+ *
+ */
+public class GeneratorRSAKey {
+    
+    public static void main(String[] args) {
+        jdkRSA();
+    }
+    
+    public static void jdkRSA() {
+        GeneratorRSAKey generatorRSAKey = new GeneratorRSAKey();
+        
+        try {
+            // 初始化密钥,产生公钥私钥对
+            Object[] keyPairArr = generatorRSAKey.initSecretkey();
+            RSAPublicKey rsaPublicKey = (RSAPublicKey) keyPairArr[0];
+            RSAPrivateKey rsaPrivateKey = (RSAPrivateKey) keyPairArr[1];
+            
+            System.out.println("------------------PublicKey------------------");
+            System.out.println(Base64.getEncoder().encodeToString(rsaPublicKey.getEncoded()));
+            
+            System.out.println("\n------------------PrivateKey------------------");
+            System.out.println(Base64.getEncoder().encodeToString(rsaPrivateKey.getEncoded()));
+        } catch (NoSuchAlgorithmException e) {
+            e.printStackTrace();
+        }
+        
+    }
+    
+    /**  
+     * 初始化密钥,生成公钥私钥对
+     * 
+     * @return Object[]
+     * @throws NoSuchAlgorithmException
+     */
+    private    Object[] initSecretkey() throws NoSuchAlgorithmException {
+        KeyPairGenerator  keyPairGenerator = KeyPairGenerator.getInstance("RSA");
+        keyPairGenerator.initialize(512);
+        KeyPair keyPair = keyPairGenerator.generateKeyPair();
+        
+        RSAPublicKey rsaPublicKey = (RSAPublicKey) keyPair.getPublic();
+        RSAPrivateKey rsaPrivateKey = (RSAPrivateKey) keyPair.getPrivate();
+        
+        Object[] keyPairArr = new Object[2];
+        keyPairArr[0] = rsaPublicKey;
+        keyPairArr[1] = rsaPrivateKey;
+        
+        return keyPairArr;
+    }
+}

+ 84 - 0
huimv-smart-management/src/main/java/com/huimv/management/rsa/JdkSignatureUtil.java

@@ -0,0 +1,84 @@
+package com.huimv.management.rsa;
+
+import java.security.InvalidKeyException;
+import java.security.KeyFactory;
+import java.security.NoSuchAlgorithmException;
+import java.security.PrivateKey;
+import java.security.PublicKey;
+import java.security.Signature;
+import java.security.SignatureException;
+import java.security.spec.InvalidKeySpecException;
+import java.security.spec.PKCS8EncodedKeySpec;
+import java.security.spec.X509EncodedKeySpec;
+import java.util.Base64;
+
+/**
+ * @description RSA签名工具类
+ * 
+ * @author admin
+ *
+ */
+public class JdkSignatureUtil {
+    
+    private final static String RSA = "RSA";
+    
+    private final static String MD5_WITH_RSA = "MD5withRSA";
+    
+    /**
+     * 执行签名
+     * 
+     * @param rsaPrivateKey  私钥
+     * @param toSignStr  参数内容
+     * @return  签名后的内容,base64后的字符串
+     * @throws NoSuchAlgorithmException
+     * @throws InvalidKeySpecException
+     * @throws InvalidKeyException
+     * @throws SignatureException
+     */
+    public static String executeSignature(String rsaPrivateKey, String toSignStr) throws NoSuchAlgorithmException, InvalidKeySpecException, InvalidKeyException, SignatureException {
+        // base64解码私钥
+        byte[] decodePrivateKey = Base64.getDecoder().decode(rsaPrivateKey.replace("\r\n", ""));
+        
+        PKCS8EncodedKeySpec pkcs8EncodedKeySpec = new PKCS8EncodedKeySpec(decodePrivateKey);
+        KeyFactory keyFactory = KeyFactory.getInstance(RSA);
+        PrivateKey privateKey = keyFactory.generatePrivate(pkcs8EncodedKeySpec);
+        Signature signature = Signature.getInstance(MD5_WITH_RSA);
+        signature.initSign(privateKey);
+        signature.update(toSignStr.getBytes());
+        
+        // 生成签名
+        byte[] result = signature.sign();
+        
+        // base64编码签名为字符串
+        return Base64.getEncoder().encodeToString(result);
+    }
+    
+    /**
+     * 验证签名
+     * 
+     * @param rsaPublicKey  公钥
+     * @param sign  签名
+     * @param src  参数内容
+     * @return  验证结果
+     * @throws NoSuchAlgorithmException
+     * @throws InvalidKeySpecException
+     * @throws InvalidKeyException
+     * @throws SignatureException
+     */
+    public static boolean verifySignature(String rsaPublicKey, String sign, String src) throws NoSuchAlgorithmException, InvalidKeySpecException, InvalidKeyException, SignatureException {
+        // base64解码公钥
+        byte[] decodePublicKey = Base64.getDecoder().decode(rsaPublicKey.replace("\r\n", ""));
+        
+        X509EncodedKeySpec x509EncodedKeySpec = new X509EncodedKeySpec(decodePublicKey);
+        KeyFactory keyFactory = KeyFactory.getInstance(RSA);
+        PublicKey publicKey = keyFactory.generatePublic(x509EncodedKeySpec);
+        Signature signature = Signature.getInstance(MD5_WITH_RSA);
+        signature.initVerify(publicKey);
+        signature.update(src.getBytes());
+        // base64解码签名为字节数组
+        byte[] decodeSign = Base64.getDecoder().decode(sign);
+
+        // 验证签名
+        return signature.verify(decodeSign);
+    }
+}

+ 202 - 0
huimv-smart-management/src/main/java/com/huimv/management/rsa/RSA.java

@@ -0,0 +1,202 @@
+//package com.huimv.management.rsa;/*
+// --------------------------------------------**********--------------------------------------------
+//
+// 该算法于1977年由美国麻省理工学院MIT(Massachusetts Institute of Technology)的Ronal Rivest,Adi Shamir和Len Adleman三位年轻教授提出,并以三人的姓氏Rivest,Shamir和Adlernan命名为RSA算法,是一个支持变长密钥的公共密钥算法,需要加密的文件快的长度也是可变的!
+//
+// 所谓RSA加密算法,是世界上第一个非对称加密算法,也是数论的第一个实际应用。它的算法如下:
+//
+// 1.找两个非常大的质数p和q(通常p和q都有155十进制位或都有512十进制位)并计算n=pq,k=(p-1)(q-1)。
+//
+// 2.将明文编码成整数M,保证M不小于0但是小于n。
+//
+// 3.任取一个整数e,保证e和k互质,而且e不小于0但是小于k。加密钥匙(称作公钥)是(e, n)。
+//
+// 4.找到一个整数d,使得ed除以k的余数是1(只要e和n满足上面条件,d肯定存在)。解密钥匙(称作密钥)是(d, n)。
+//
+// 加密过程: 加密后的编码C等于M的e次方除以n所得的余数。
+//
+// 解密过程: 解密后的编码N等于C的d次方除以n所得的余数。
+//
+// 只要e、d和n满足上面给定的条件。M等于N。
+//
+// --------------------------------------------**********--------------------------------------------
+// */
+//import java.math.BigInteger;
+//import java.security.Key;
+//import java.security.KeyFactory;
+//import java.security.KeyPair;
+//import java.security.KeyPairGenerator;
+//import java.security.PrivateKey;
+//import java.security.PublicKey;
+//import java.security.SecureRandom;
+//import java.security.Signature;
+//import java.security.interfaces.RSAPublicKey;
+//import java.security.spec.PKCS8EncodedKeySpec;
+//import java.security.spec.X509EncodedKeySpec;
+//import java.util.HashMap;
+//import java.util.Map;
+//
+//import javax.crypto.Cipher;
+//
+//
+//import com.github.structlog4j.ILogger;
+//import com.github.structlog4j.SLoggerFactory;
+//
+//public class RSA {
+//    private static final ILogger log = SLoggerFactory.getLogger(RSA.class);
+//    /** 指定key的大小 */
+//    private static int KEYSIZE = 2048;
+//    /**
+//     * 生成密钥对
+//     */
+//    public static Map<String, String> generateKeyPair() throws Exception {
+//        /** RSA算法要求有一个可信任的随机数源 */
+//        SecureRandom sr = new SecureRandom();
+//        /** 为RSA算法创建一个KeyPairGenerator对象 */
+//        KeyPairGenerator kpg = KeyPairGenerator.getInstance("RSA");
+//        /** 利用上面的随机数据源初始化这个KeyPairGenerator对象 */
+//        kpg.initialize(KEYSIZE, sr);
+//        /** 生成密匙对 */
+//        KeyPair kp = kpg.generateKeyPair();
+//        /** 得到公钥 */
+//        Key publicKey = kp.getPublic();
+//        byte[] publicKeyBytes = publicKey.getEncoded();
+//        String pub = new String(Base64Sign.encodeBase64(publicKeyBytes),
+//                ConfigureEncryptAndDecrypt.CHAR_ENCODING);
+//        /** 得到私钥 */
+//        Key privateKey = kp.getPrivate();
+//        byte[] privateKeyBytes = privateKey.getEncoded();
+//        String pri = new String(Base64Sign.encodeBase64(privateKeyBytes),
+//                ConfigureEncryptAndDecrypt.CHAR_ENCODING);
+//
+//        Map<String, String> map = new HashMap<String, String>();
+//        map.put("publicKey", pub);
+//        map.put("privateKey", pri);
+//        RSAPublicKey rsp = (RSAPublicKey) kp.getPublic();
+//        BigInteger bint = rsp.getModulus();
+//        byte[] b = bint.toByteArray();
+//        byte[] deBase64Value = Base64Sign.encodeBase64(b);
+//        String retValue = new String(deBase64Value);
+//        map.put("modulus", retValue);
+//        return map;
+//    }
+//
+//    /**
+//     * 加密方法 source: 源数据
+//     */
+//    public static String encrypt(String source, String publicKey)
+//            throws Exception {
+//        Key key = getPublicKey(publicKey);
+//        /** 得到Cipher对象来实现对源数据的RSA加密 */
+//        Cipher cipher = Cipher.getInstance(ConfigureEncryptAndDecrypt.RSA_ALGORITHM);
+//        cipher.init(Cipher.ENCRYPT_MODE, key);
+//        byte[] b = source.getBytes();
+//        /** 执行加密操作 */
+//        byte[] b1 = cipher.doFinal(b);
+//        return new String(Base64Sign.encodeBase64(b1),
+//                ConfigureEncryptAndDecrypt.CHAR_ENCODING);
+//    }
+//
+//    /**
+//     * 解密算法 cryptograph:密文
+//     */
+//    public static String decrypt(String cryptograph, String privateKey)
+//            throws Exception {
+//        Key key = getPrivateKey(privateKey);
+//        /** 得到Cipher对象对已用公钥加密的数据进行RSA解密 */
+//        Cipher cipher = Cipher.getInstance(ConfigureEncryptAndDecrypt.RSA_ALGORITHM);
+//        cipher.init(Cipher.DECRYPT_MODE, key);
+//        byte[] b1 = Base64Sign.decodeBase64(cryptograph.getBytes());
+//        /** 执行解密操作 */
+//        byte[] b = cipher.doFinal(b1);
+//        return new String(b);
+//    }
+//
+//    /**
+//     * 得到公钥
+//     *
+//     * @param key
+//     *            密钥字符串(经过base64编码)
+//     * @throws Exception
+//     */
+//    public static PublicKey getPublicKey(String key) throws Exception {
+//        X509EncodedKeySpec keySpec = new X509EncodedKeySpec(
+//                Base64Sign.decodeBase64(key.getBytes()));
+//        KeyFactory keyFactory = KeyFactory.getInstance("RSA");
+//        PublicKey publicKey = keyFactory.generatePublic(keySpec);
+//        return publicKey;
+//    }
+//
+//    /**
+//     * 得到私钥
+//     *
+//     * @param key
+//     *            密钥字符串(经过base64编码)
+//     * @throws Exception
+//     */
+//    public static PrivateKey getPrivateKey(String key) throws Exception {
+//        PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(
+//                Base64Sign.decodeBase64(key.getBytes()));
+//        KeyFactory keyFactory = KeyFactory.getInstance("RSA");
+//        PrivateKey privateKey = keyFactory.generatePrivate(keySpec);
+//        return privateKey;
+//    }
+//
+//    public static String sign(String content, String privateKey) {
+//        String charset = ConfigureEncryptAndDecrypt.CHAR_ENCODING;
+//        try {
+//            PKCS8EncodedKeySpec priPKCS8 = new PKCS8EncodedKeySpec(
+//                    Base64Sign.decodeBase64(privateKey.getBytes()));
+//            KeyFactory keyf = KeyFactory.getInstance("RSA");
+//            PrivateKey priKey = keyf.generatePrivate(priPKCS8);
+//
+//            Signature signature = Signature.getInstance("SHA256WithRSA");
+//
+//            signature.initSign(priKey);
+//            signature.update(content.getBytes(charset));
+//
+//            byte[] signed = signature.sign();
+//
+//            return new String(Base64Sign.encodeBase64(signed));
+//        } catch (Exception e) {
+//
+//        }
+//
+//        return null;
+//    }
+//
+//    public static boolean checkSign(String content, String sign, String publicKey)
+//    {
+//        try
+//        {
+//            KeyFactory keyFactory = KeyFactory.getInstance("RSA");
+//            byte[] encodedKey = Base64Sign.decode2(publicKey);
+//            PublicKey pubKey = keyFactory.generatePublic(new X509EncodedKeySpec(encodedKey));
+//
+//
+//            java.security.Signature signature = java.security.Signature
+//            .getInstance("SHA256WithRSA");
+//
+//            signature.initVerify(pubKey);
+//            signature.update( content.getBytes("utf-8") );
+//
+//            boolean bverify = signature.verify( Base64Sign.decode2(sign) );
+//            return bverify;
+//
+//        }
+//        catch (Exception e)
+//        {
+//            log.error("RSA-checkSign Exception", e);
+//        }
+//
+//        return false;
+//    }
+//
+//    public static void main(String[] args) throws Exception {
+//
+//        for(String key : generateKeyPair().keySet()) {
+//            System.out.println(key + ":");
+//            System.out.println(generateKeyPair().get(key));
+//        }
+//    }
+//}

+ 35 - 0
huimv-smart-management/src/main/java/com/huimv/management/rsa/RSAUtil.java

@@ -0,0 +1,35 @@
+//package com.huimv.management.rsa;
+//
+//import org.apache.tomcat.util.codec.binary.Base64;
+//
+//import java.security.KeyFactory;
+//import java.security.PrivateKey;
+//import java.security.Signature;
+//import java.security.spec.PKCS8EncodedKeySpec;
+//
+///**
+// * @Author yinhao
+// * @Date 2021/4/29 17:53
+// * @Description
+// */
+//public class RSAUtil {
+//
+//    public static void main(String[] args) {
+//        String channelId = "1018";
+//        int random = (int) ((Math.random() * 9 + 1) * 100000);
+//        long timestamp = System.currentTimeMillis();
+//        String data = channelId + ";" + random + ";" + timestamp;
+//        String sign = getPinAnSign(data.getBytes("UTF-8"), Constants.RSA_SIGN_PRIVATE_KEY);
+//    }
+//
+//    private static String getPinAnSign(byte[] data, String privateKey) throws Exception {
+//        byte[] keyBytes = Base64.decodeBase64(privateKey);
+//        PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes);
+//        KeyFactory keyFactory = KeyFactory.getInstance("RSA");
+//        PrivateKey privateKey1 = keyFactory.generatePrivate(pkcs8KeySpec);
+//        Signature signature = Signature.getInstance("MD5withRSA");
+//        signature.initSign(privateKey1);
+//        signature.update(data);
+//    }
+//
+//}

+ 48 - 0
huimv-smart-management/src/main/java/com/huimv/management/rsa/ServerController.java

@@ -0,0 +1,48 @@
+package com.huimv.management.rsa;
+
+import java.io.UnsupportedEncodingException;
+import java.net.URLDecoder;
+import java.nio.charset.StandardCharsets;
+import java.security.InvalidKeyException;
+import java.security.NoSuchAlgorithmException;
+import java.security.SignatureException;
+import java.security.spec.InvalidKeySpecException;
+import java.util.Comparator;
+import java.util.Map;
+
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RestController;
+
+@RestController
+public class ServerController {
+
+    // 公钥
+//    private final static String PUBLIC_KEY = "MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBAJz1kfGpz7dGFZCUY/kXbvYBXZEd5Xg+S8SRRD+p2iGCeQlKJ+Fycuboe7hIr8jhyTEKpaOFN8wW5/QNXdOzDnMCAwEAAQ==";
+    private final static String PUBLIC_KEY = "MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBAIvJs0JQAJJZ9VYKyo69ByDYzDpCTjyu/bUcw+7SI1PqZtliUYmjUmaQdzKigCjpQH2Sq3x+VSmfnprZhP6COYkCAwEAAQ==";
+
+    @PostMapping(value = "/test")
+    public String server(@RequestBody Map<String, Object> param) throws InvalidKeySpecException,
+            NoSuchAlgorithmException, InvalidKeyException, SignatureException, UnsupportedEncodingException {
+        // 从参数中取出签名字符串并删除,因为sign不参与字符串拼接
+        String sign = (String) param.remove("sign");
+        // 对签名字符串进行url解码
+        String decodeSign = URLDecoder.decode(sign, "UTF-8");
+//        String decodeSign = URLDecoder.decode(sign, StandardCharsets.UTF_8.toString());
+
+        // 将签名的参数内容按参数名的字典顺序进行排序,并拼接为字符串
+        StringBuilder sb = new StringBuilder();
+        param.entrySet().stream().sorted(Comparator.comparing(Map.Entry::getKey)).forEach(entry ->
+                sb.append(entry.getKey()).append("=").append(entry.getValue()).append("&")
+        );
+        String paramStr = sb.toString().substring(0, sb.length() - 1);
+
+        // 使用公钥进行验签
+        boolean result = JdkSignatureUtil.verifySignature(PUBLIC_KEY, decodeSign, paramStr);
+        if (result) {
+            return "签名验证成功";
+        }
+
+        return "签名验证失败,非法请求";
+    }
+}

+ 38 - 0
huimv-smart-management/src/main/java/com/huimv/management/rsa/SignRSAUtil.java

@@ -0,0 +1,38 @@
+package com.huimv.management.rsa;
+
+import org.apache.tomcat.util.codec.binary.Base64;
+
+import java.security.KeyFactory;
+import java.security.PrivateKey;
+import java.security.Signature;
+import java.security.spec.PKCS8EncodedKeySpec;
+
+/**
+ * @Author yinhao
+ * @Date 2021/4/30 13:22
+ * @Description
+ */
+public class SignRSAUtil {
+
+    public static void main(String[] args) {
+        String channelId = "1018";
+        int random = (int) ((Math.random() * 9 + 1) * 100000);
+        long timestamp = System.currentTimeMillis();
+        String data = channelId + ";" + random + ";" + timestamp;
+
+//        getPinAnSign(data.getBytes(StandardCharsets.UTF_8),)
+        String sign = null;
+    }
+
+    public static String getPinAnSign(byte[] data, String privatekey) throws Exception {
+        byte[] keyBytes = Base64.decodeBase64(privatekey);
+        PKCS8EncodedKeySpec pkcs8EncodedKeySpec = new PKCS8EncodedKeySpec(keyBytes);
+        KeyFactory keyFactory = KeyFactory.getInstance("RSA");
+        PrivateKey privateKey1 = keyFactory.generatePrivate(pkcs8EncodedKeySpec);
+        Signature signature = Signature.getInstance("MD5withRSA");
+        signature.initSign(privateKey1);
+        signature.update(data);
+
+        return new String(Base64.encodeBase64(signature.sign()));
+    }
+}

+ 20 - 0
huimv-smart-management/src/main/java/com/huimv/management/service/TestService.java

@@ -0,0 +1,20 @@
+package com.huimv.management.service;
+
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.huimv.common.utils.PageUtils;
+import com.huimv.management.entity.TestEntity;
+
+import java.util.Map;
+
+/**
+ * 
+ *
+ * @author yinhao
+ * @email yinhao@163.com
+ * @date 2021-04-28 19:33:24
+ */
+public interface TestService extends IService<TestEntity> {
+
+    PageUtils queryPage(Map<String, Object> params);
+}
+

+ 29 - 0
huimv-smart-management/src/main/java/com/huimv/management/service/impl/TestServiceImpl.java

@@ -0,0 +1,29 @@
+package com.huimv.management.service.impl;
+
+import org.springframework.stereotype.Service;
+import java.util.Map;
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.huimv.common.utils.PageUtils;
+import com.huimv.common.utils.Query;
+
+import com.huimv.management.dao.TestDao;
+import com.huimv.management.entity.TestEntity;
+import com.huimv.management.service.TestService;
+
+
+@Service("testService")
+public class TestServiceImpl extends ServiceImpl<TestDao, TestEntity> implements TestService {
+
+    @Override
+    public PageUtils queryPage(Map<String, Object> params) {
+        IPage<TestEntity> page = this.page(
+                new Query<TestEntity>().getPage(params),
+                new QueryWrapper<TestEntity>()
+        );
+
+        return new PageUtils(page);
+    }
+
+}

+ 1 - 1
huimv-smart-management/src/main/resources/application-dev.yml

@@ -24,7 +24,7 @@ spring:
     type: com.alibaba.druid.pool.DruidDataSource
     druid:
       driver-class-name: com.mysql.cj.jdbc.Driver
-      url: jdbc:mysql://localhost:3306/huimv_smart_msg?useUnicode=true&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai
+      url: jdbc:mysql://localhost:3306/huimv_smart_mgt?useUnicode=true&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai
       username: root
       password: root
       initial-size: 10

+ 14 - 0
huimv-smart-management/src/main/resources/mapper/management/TestDao.xml

@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+
+<mapper namespace="com.huimv.management.dao.TestDao">
+
+	<!-- 可根据自己的需求,是否要使用 -->
+    <resultMap type="com.huimv.management.entity.TestEntity" id="testMap">
+        <result property="name" column="name"/>
+        <result property="address" column="address"/>
+        <result property="age" column="age"/>
+    </resultMap>
+
+
+</mapper>

+ 6 - 0
renren-fast/pom.xml

@@ -55,6 +55,12 @@
             <groupId>com.huimv</groupId>
             <artifactId>huimv-smart-common</artifactId>
             <version>1.0-SNAPSHOT</version>
+            <exclusions>
+                <exclusion>
+                    <groupId>com.baomidou</groupId>
+                    <artifactId>mybatis-plus-boot-starter</artifactId>
+                </exclusion>
+            </exclusions>
         </dependency>
         <dependency>
             <groupId>org.springframework.boot</groupId>

+ 3 - 1
renren-fast/src/main/java/io/renren/RenrenApplication.java

@@ -8,11 +8,13 @@
 
 package io.renren;
 
+import com.huimv.common.autoconfigure.MybatisPlusConfiguration;
+import org.mybatis.spring.annotation.MapperScan;
 import org.springframework.boot.SpringApplication;
 import org.springframework.boot.autoconfigure.SpringBootApplication;
 
 
-@SpringBootApplication
+@SpringBootApplication(exclude = MybatisPlusConfiguration.class)
 //@EnableDiscoveryClient
 public class RenrenApplication {
 

+ 1 - 1
renren-generator/src/main/resources/application.yml

@@ -7,7 +7,7 @@ spring:
     type: com.alibaba.druid.pool.DruidDataSource
     #MySQL配置
     driverClassName: com.mysql.cj.jdbc.Driver
-    url: jdbc:mysql://localhost:3306/huimv_smart_msg?useUnicode=true&characterEncoding=UTF-8&useSSL=false&serverTimezone=Asia/Shanghai
+    url: jdbc:mysql://localhost:3306/huimv_smart_mgt?useUnicode=true&characterEncoding=UTF-8&useSSL=false&serverTimezone=Asia/Shanghai
     username: root
     password: root
     #oracle配置