Просмотр исходного кода

1.alarm_user表添加字段RULELEVEL
//0,1,2 0为最低权限仅可以查看为0的规则,1为普通权限可以查看为0,1的规则,2为超级权限可以查看所有规则
2.alertrule表添加字段 ruleLevel字段
3.warning-web配置文件添加rule_encryption,rule_encryption_key属性,当rule_encryption为true时,代表规则进行加密,且密钥为rule_encryption_key的值,默认为gyee-alarm123456,加密解密方法为java/com/gyee/wisdom/alarm/sharding/service/Alertrule2Service.java 中的pageQueryAll方法

wanghs 1 год назад
Родитель
Сommit
3711b3ed32
100 измененных файлов с 5332 добавлено и 137 удалено
  1. 118 3
      common/utils/src/main/java/com/gyee/wisdom/common/utils/EncryptUtil.java
  2. 5 5
      dao/dao-sql/src/main/java/com/gyee/wisdom/dao/sql/alarm/Entity/AlertsnapNewEntity.java
  3. 9 9
      risk-calc/src/main/resources/application.yaml
  4. 1 1
      risk-calc/src/main/resources/mappers-postgresql/AlarmSnapMapper.xml
  5. 16 0
      sample-kudu/src/main/java/com/gyee/wisdom/KuduSampleApplication.java
  6. 23 0
      sample-kudu/src/main/java/com/gyee/wisdom/samplekudu/ApplicationReadyEventListener.java
  7. 200 0
      sample-kudu/src/main/java/com/gyee/wisdom/samplekudu/LcingCalc.java
  8. 45 0
      sample-kudu/src/main/java/com/gyee/wisdom/samplekudu/advice/ControllerExecptionAdvice.java
  9. 42 0
      sample-kudu/src/main/java/com/gyee/wisdom/samplekudu/advice/ControllerResponseAdvice.java
  10. 17 0
      sample-kudu/src/main/java/com/gyee/wisdom/samplekudu/advice/NotControllerResponseAdvice.java
  11. 315 0
      sample-kudu/src/main/java/com/gyee/wisdom/samplekudu/biz/LcingSampleImportBiz.java
  12. 27 0
      sample-kudu/src/main/java/com/gyee/wisdom/samplekudu/config/ConfigProperties.java
  13. 69 0
      sample-kudu/src/main/java/com/gyee/wisdom/samplekudu/controller/LcingSampleController.java
  14. 143 0
      sample-kudu/src/main/java/com/gyee/wisdom/samplekudu/domain/data/LcingTagNameData.java
  15. 103 0
      sample-kudu/src/main/java/com/gyee/wisdom/samplekudu/domain/input/InputLcing.java
  16. 64 0
      sample-kudu/src/main/java/com/gyee/wisdom/samplekudu/entity/LcingSampleEntity.java
  17. 64 0
      sample-kudu/src/main/java/com/gyee/wisdom/samplekudu/entity/TsPointEntity.java
  18. 35 0
      sample-kudu/src/main/java/com/gyee/wisdom/samplekudu/entity/WindturbineEntity.java
  19. 30 0
      sample-kudu/src/main/java/com/gyee/wisdom/samplekudu/exception/APIException.java
  20. 39 0
      sample-kudu/src/main/java/com/gyee/wisdom/samplekudu/exception/APIRunTimeException.java
  21. 30 0
      sample-kudu/src/main/java/com/gyee/wisdom/samplekudu/exception/TaosRunException.java
  22. 28 0
      sample-kudu/src/main/java/com/gyee/wisdom/samplekudu/kudu/KuduConnection.java
  23. 103 0
      sample-kudu/src/main/java/com/gyee/wisdom/samplekudu/lcingcalc/CacheService.java
  24. 322 0
      sample-kudu/src/main/java/com/gyee/wisdom/samplekudu/lcingcalc/LcingCalcTask.java
  25. 96 0
      sample-kudu/src/main/java/com/gyee/wisdom/samplekudu/lcingcalc/TagInfo.java
  26. 14 0
      sample-kudu/src/main/java/com/gyee/wisdom/samplekudu/mapper/TsPointMapper.java
  27. 11 0
      sample-kudu/src/main/java/com/gyee/wisdom/samplekudu/mapper/WindturbineMapper.java
  28. 28 0
      sample-kudu/src/main/java/com/gyee/wisdom/samplekudu/service/TsPointService.java
  29. 28 0
      sample-kudu/src/main/java/com/gyee/wisdom/samplekudu/service/WindturbineService.java
  30. 86 0
      sample-kudu/src/main/java/com/gyee/wisdom/samplekudu/taos/TaosConfig.java
  31. 75 0
      sample-kudu/src/main/java/com/gyee/wisdom/samplekudu/taos/TaosHistoryDao.java
  32. 76 0
      sample-kudu/src/main/java/com/gyee/wisdom/samplekudu/taos/TaskCallable.java
  33. 57 0
      sample-kudu/src/main/java/com/gyee/wisdom/samplekudu/taos/ThreadPoolTaskConfig.java
  34. 46 0
      sample-kudu/src/main/java/com/gyee/wisdom/samplekudu/timeseries/BaseTsQuery.java
  35. 38 0
      sample-kudu/src/main/java/com/gyee/wisdom/samplekudu/timeseries/BasicTsData.java
  36. 62 0
      sample-kudu/src/main/java/com/gyee/wisdom/samplekudu/timeseries/BasicTsPoint.java
  37. 24 0
      sample-kudu/src/main/java/com/gyee/wisdom/samplekudu/timeseries/BlobTsData.java
  38. 22 0
      sample-kudu/src/main/java/com/gyee/wisdom/samplekudu/timeseries/BlobWriteTsData.java
  39. 19 0
      sample-kudu/src/main/java/com/gyee/wisdom/samplekudu/timeseries/BooleanTsData.java
  40. 19 0
      sample-kudu/src/main/java/com/gyee/wisdom/samplekudu/timeseries/BooleanWriteTsData.java
  41. 18 0
      sample-kudu/src/main/java/com/gyee/wisdom/samplekudu/timeseries/Coordinate.java
  42. 26 0
      sample-kudu/src/main/java/com/gyee/wisdom/samplekudu/timeseries/CoordinateTsData.java
  43. 21 0
      sample-kudu/src/main/java/com/gyee/wisdom/samplekudu/timeseries/CoordinateWriteTsData.java
  44. 30 0
      sample-kudu/src/main/java/com/gyee/wisdom/samplekudu/timeseries/DoubleStatData.java
  45. 33 0
      sample-kudu/src/main/java/com/gyee/wisdom/samplekudu/timeseries/DoubleTsData.java
  46. 19 0
      sample-kudu/src/main/java/com/gyee/wisdom/samplekudu/timeseries/DoubleWriteTsData.java
  47. 28 0
      sample-kudu/src/main/java/com/gyee/wisdom/samplekudu/timeseries/GeneralTsData.java
  48. 18 0
      sample-kudu/src/main/java/com/gyee/wisdom/samplekudu/timeseries/IntegerTsData.java
  49. 8 0
      sample-kudu/src/main/java/com/gyee/wisdom/samplekudu/timeseries/Interpolation.java
  50. 24 0
      sample-kudu/src/main/java/com/gyee/wisdom/samplekudu/timeseries/LongTsData.java
  51. 20 0
      sample-kudu/src/main/java/com/gyee/wisdom/samplekudu/timeseries/LongWriteTsData.java
  52. 24 0
      sample-kudu/src/main/java/com/gyee/wisdom/samplekudu/timeseries/StringTsData.java
  53. 20 0
      sample-kudu/src/main/java/com/gyee/wisdom/samplekudu/timeseries/StringWriteTsData.java
  54. 15 0
      sample-kudu/src/main/java/com/gyee/wisdom/samplekudu/timeseries/TsData.java
  55. 15 0
      sample-kudu/src/main/java/com/gyee/wisdom/samplekudu/timeseries/TsDataType.java
  56. 21 0
      sample-kudu/src/main/java/com/gyee/wisdom/samplekudu/timeseries/TsPoint.java
  57. 60 0
      sample-kudu/src/main/java/com/gyee/wisdom/samplekudu/timeseries/TsPointData.java
  58. 23 0
      sample-kudu/src/main/java/com/gyee/wisdom/samplekudu/timeseries/TsPointDataList.java
  59. 21 0
      sample-kudu/src/main/java/com/gyee/wisdom/samplekudu/timeseries/TsQuery.java
  60. 26 0
      sample-kudu/src/main/java/com/gyee/wisdom/samplekudu/timeseries/websocket/SubscribeMessaage.java
  61. 33 0
      sample-kudu/src/main/java/com/gyee/wisdom/samplekudu/transport/AlarmSnap.java
  62. 54 0
      sample-kudu/src/main/java/com/gyee/wisdom/samplekudu/transport/AlarmSnapService.java
  63. 33 0
      sample-kudu/src/main/java/com/gyee/wisdom/samplekudu/transport/RemoteServiceBuilder.java
  64. 100 0
      sample-kudu/src/main/java/com/gyee/wisdom/samplekudu/transport/RestfulClient.java
  65. 22 0
      sample-kudu/src/main/java/com/gyee/wisdom/samplekudu/util/AppCode.java
  66. 15 0
      sample-kudu/src/main/java/com/gyee/wisdom/samplekudu/util/ChineseDes.java
  67. 90 0
      sample-kudu/src/main/java/com/gyee/wisdom/samplekudu/util/CsvExportUtil.java
  68. 192 0
      sample-kudu/src/main/java/com/gyee/wisdom/samplekudu/util/DateUtils.java
  69. 17 0
      sample-kudu/src/main/java/com/gyee/wisdom/samplekudu/util/PassToken.java
  70. 23 0
      sample-kudu/src/main/java/com/gyee/wisdom/samplekudu/util/ResultCode.java
  71. 46 0
      sample-kudu/src/main/java/com/gyee/wisdom/samplekudu/util/ResultVo.java
  72. 161 0
      sample-kudu/src/main/java/com/gyee/wisdom/samplekudu/util/SnowflakeGenerator.java
  73. 113 0
      sample-kudu/src/main/java/com/gyee/wisdom/samplekudu/util/SpringContextUtil.java
  74. 7 0
      sample-kudu/src/main/java/com/gyee/wisdom/samplekudu/util/StatusCode.java
  75. 530 0
      sample-kudu/src/main/java/com/gyee/wisdom/samplekudu/util/StringUtil.java
  76. 35 0
      sample-kudu/src/main/java/com/gyee/wisdom/samplekudu/util/TimeService.java
  77. 8 0
      sample-kudu/src/main/java/com/gyee/wisdom/samplekudu/util/UUIDUtil.java
  78. 17 0
      sample-kudu/src/main/java/com/gyee/wisdom/samplekudu/util/UserLoginToken.java
  79. 101 0
      sample-kudu/src/main/resources/application.yml
  80. 35 0
      sample-kudu/src/main/resources/readme.md
  81. 1 0
      sample-kudu/src/main/resources/sql/lcing_sample.sql
  82. 323 0
      sample-kudu/src/test/java/com/gyee/wisdom/samplekudu/MyTest.java
  83. 1 0
      settings.gradle
  84. 11 6
      warning-web/build.gradle
  85. 9 0
      warning-web/src/main/java/com/gyee/wisdom/alarm/sharding/config/MyConfig.java
  86. 2 2
      warning-web/src/main/java/com/gyee/wisdom/alarm/sharding/controller/AlarmUserController.java
  87. 29 15
      warning-web/src/main/java/com/gyee/wisdom/alarm/sharding/controller/Alertrule2Controller.java
  88. 1 1
      warning-web/src/main/java/com/gyee/wisdom/alarm/sharding/controller/DeviceController.java
  89. 2 0
      warning-web/src/main/java/com/gyee/wisdom/alarm/sharding/controller/InfoController.java
  90. 68 9
      warning-web/src/main/java/com/gyee/wisdom/alarm/sharding/controller/TestController.java
  91. 4 0
      warning-web/src/main/java/com/gyee/wisdom/alarm/sharding/entity/AlarmUser.java
  92. 22 22
      warning-web/src/main/java/com/gyee/wisdom/alarm/sharding/entity/Alertrule2.java
  93. 1 1
      warning-web/src/main/java/com/gyee/wisdom/alarm/sharding/entity/WindTurbineTestingPointAi.java
  94. 2 0
      warning-web/src/main/java/com/gyee/wisdom/alarm/sharding/entity/WindTurbineTestingPointDi.java
  95. 88 0
      warning-web/src/main/java/com/gyee/wisdom/alarm/sharding/exception/GloabalExceptionHandler.java
  96. 6 5
      warning-web/src/main/java/com/gyee/wisdom/alarm/sharding/filter/LoginInterceptor.java
  97. 18 17
      warning-web/src/main/java/com/gyee/wisdom/alarm/sharding/schedule/CreateTablesScheduled.java
  98. 79 35
      warning-web/src/main/java/com/gyee/wisdom/alarm/sharding/service/Alertrule2Service.java
  99. 14 6
      warning-web/src/main/java/com/gyee/wisdom/alarm/sharding/util/TokenUtil.java
  100. 0 0
      warning-web/src/main/resources/application.yaml

+ 118 - 3
common/utils/src/main/java/com/gyee/wisdom/common/utils/EncryptUtil.java

@@ -2,13 +2,14 @@ package com.gyee.wisdom.common.utils;
 
 import org.apache.commons.codec.binary.Base64;
 
-import javax.crypto.KeyGenerator;
-import javax.crypto.Mac;
-import javax.crypto.SecretKey;
+import javax.crypto.*;
+import javax.crypto.spec.DESKeySpec;
 import javax.crypto.spec.SecretKeySpec;
+import java.nio.charset.StandardCharsets;
 import java.security.InvalidKeyException;
 import java.security.MessageDigest;
 import java.security.NoSuchAlgorithmException;
+import java.security.SecureRandom;
 
 public class EncryptUtil {
     public static final String KEY_SHA = "SHA";
@@ -126,4 +127,118 @@ public class EncryptUtil {
 //        System.out.println(new BigInteger(encryptHMAC(data.getBytes(), initMacKey())).toString());
     }
 
+    /**
+     * @param
+     * @param datasource
+     * @param password
+     * @return
+     * @return byte[]
+     * @author Wanghs
+     * @description DES解密
+     * @date 2022/11/8
+     **/
+    public static byte[] decryptDES(byte[] datasource, String password) {
+        try {
+            // DES算法要求有一个可信任的随机数源
+            SecureRandom random = new SecureRandom();
+            // 创建一个DESKeySpec对象
+            DESKeySpec desKey = new DESKeySpec(password.getBytes(StandardCharsets.UTF_8));
+            // 创建一个密匙工厂
+            SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES");
+            // 将DESKeySpec对象转换成SecretKey对象
+            SecretKey securekey = keyFactory.generateSecret(desKey);
+            // Cipher对象实际完成解密操作
+            Cipher cipher = Cipher.getInstance("DES");
+            // 用密匙初始化Cipher对象
+            cipher.init(Cipher.DECRYPT_MODE, securekey, random);
+            // 真正开始解密操作
+            return cipher.doFinal(datasource);
+        } catch (Exception ex) {
+            ex.printStackTrace();
+        }
+        return null;
+    }
+
+    /**
+     * @param
+     * @param datasource
+     * @param password
+     * @return
+     * @return byte[]
+     * @author Wanghs
+     * @description DES加密
+     * @date 2022/11/8
+     **/
+    public static byte[] encryptDES(byte[] datasource, String password) {
+        try {
+            SecureRandom random = new SecureRandom();
+            DESKeySpec desKey = new DESKeySpec(password.getBytes(StandardCharsets.UTF_8));
+            //创建一个密匙工厂,然后用它把DESKeySpec转换成
+            SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES");
+            SecretKey securekey = keyFactory.generateSecret(desKey);
+            //Cipher对象实际完成加密操作
+            Cipher cipher = Cipher.getInstance("DES");
+            //用密匙初始化Cipher对象
+            cipher.init(Cipher.ENCRYPT_MODE, securekey, random);
+            //现在,获取数据并加密
+            //正式执行加密操作
+            return cipher.doFinal(datasource);
+        } catch (Throwable e) {
+            e.printStackTrace();
+        }
+        return null;
+
+    }
+
+
+    // 加密
+    public static String encryptAES(String sSrc, String sKey) throws Exception {
+        if (sKey == null) {
+            System.out.print("Key为空null");
+            return null;
+        }
+        // 判断Key是否为16位
+        if (sKey.length() != 16) {
+            System.out.print("Key长度不是16位");
+            return null;
+        }
+        byte[] raw = sKey.getBytes(StandardCharsets.UTF_8);
+        SecretKeySpec skeySpec = new SecretKeySpec(raw, "AES");
+        Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");//"算法/模式/补码方式"
+        cipher.init(Cipher.ENCRYPT_MODE, skeySpec);
+        byte[] encrypted = cipher.doFinal(sSrc.getBytes(StandardCharsets.UTF_8));
+        return  Base64.encodeBase64String(encrypted);//此处使用BASE64做转码功能,同时能起到2次加密的作用。
+    }
+
+    // 解密
+    public static String decryptAES(String sSrc, String sKey) throws Exception {
+        try {
+            // 判断Key是否正确
+            if (sKey == null) {
+                System.out.print("Key为空null");
+                return null;
+            }
+            // 判断Key是否为16位
+            if (sKey.length() != 16) {
+                System.out.print("Key长度不是16位");
+                return null;
+            }
+            byte[] raw = sKey.getBytes(StandardCharsets.UTF_8);
+            SecretKeySpec skeySpec = new SecretKeySpec(raw, "AES");
+            Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
+            cipher.init(Cipher.DECRYPT_MODE, skeySpec);
+            byte[] encrypted1 = Base64.decodeBase64(sSrc);//先用base64解密
+            try {
+                byte[] original = cipher.doFinal(encrypted1);
+                String originalString = new String(original,StandardCharsets.UTF_8);
+                return originalString;
+            } catch (Exception e) {
+                System.out.println(e.toString());
+                return null;
+            }
+        } catch (Exception ex) {
+            System.out.println(ex.toString());
+            return null;
+        }
+    }
 }

+ 5 - 5
dao/dao-sql/src/main/java/com/gyee/wisdom/dao/sql/alarm/Entity/AlertsnapNewEntity.java

@@ -4,7 +4,7 @@ import com.gyee.wisdom.common.data.alarm.Alertsnap;
 import com.gyee.wisdom.common.data.alarm.AlertsnapNew;
 import lombok.Data;
 import lombok.NoArgsConstructor;
-import org.hibernate.annotations.GenericGenerator;
+//import org.hibernate.annotations.GenericGenerator;
 import org.springframework.beans.BeanUtils;
 
 import javax.persistence.*;
@@ -14,14 +14,14 @@ import java.util.Date;
 @Data
 @Entity
 @NoArgsConstructor
-@Table(name = "alertsnap_new")
-@GenericGenerator(name = "NXFD_ALERTSNAP_NEW", strategy = "NXFD_ALERTSNAP_NEW")
+@Table(name = "alertsnap")
+//@GenericGenerator(name = "NXFD_ALERTSNAP_NEW", strategy = "NXFD_ALERTSNAP_NEW")
 public class AlertsnapNewEntity implements ToData<AlertsnapNew>,Serializable{
     private static final long serialVersionUID = -8348826240826071549L;
     @Id
     @Column(name = "id")
-    @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "NXFD_ALERTSNAP_NEW")
-    @SequenceGenerator(name = "NXFD_ALERTSNAP_NEW", sequenceName = "NXFD_ALERTSNAP_NEW")
+//    @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "NXFD_ALERTSNAP_NEW")
+//    @SequenceGenerator(name = "NXFD_ALERTSNAP_NEW", sequenceName = "NXFD_ALERTSNAP_NEW")
     private Long id;
     @Column(name = "stationid")
     private String stationId;

+ 9 - 9
risk-calc/src/main/resources/application.yaml

@@ -5,14 +5,14 @@ spring:
   application:
     name: risk-calc
   datasource:
-    driver-class-name: oracle.jdbc.OracleDriver
-    url: jdbc:oracle:thin:@123.60.213.70:1521:gdnxfd
-    username: nxfdprod
-    password: gdnxfd123
-#    driver-class-name: com.mysql.jdbc.Driver
-#    url: jdbc:mysql://123.60.219.66/wisdom_cs?useUnicode=true&characterEncoding=UTF-8
-#    username: root
-#    password: gyeepd@123
+#    driver-class-name: oracle.jdbc.OracleDriver
+#    url: jdbc:oracle:thin:@123.60.213.70:1521:gdnxfd
+#    username: nxfdprod
+#    password: gdnxfd123
+    driver-class-name: com.mysql.jdbc.Driver
+    url: jdbc:mysql://15.147.0.228/wisdom_cs?useUnicode=true&characterEncoding=UTF-8
+    username: root
+    password: 123
 #    driver-class-name: org.postgresql.Driver
 #    url: jdbc:postgresql://123.60.219.66:5432/wisdom_cs
 #    username: postgres
@@ -32,7 +32,7 @@ spring:
 
 mybatis-plus:
   typeAliasesPackage: com.gyee.wisdom.riskcalc.entity
-  mapper-locations: classpath:mappers-oracle/*.xml
+  mapper-locations: classpath:mappers/*.xml
   global-config:
     #主键类型  0:"数据库ID自增", 1:"用户输入ID",2:"全局唯一ID (数字类型唯一ID)", 3:"全局唯一ID UUID";
     id-type: 3

+ 1 - 1
risk-calc/src/main/resources/mappers-postgresql/AlarmSnapMapper.xml

@@ -151,7 +151,7 @@
         alarmsnap s
         <if test="ruleType !=null and ruleType !=''">
             <if test="ruleType=='custom'">
-                left join alertrule2 r on CONVERT(s.alertvalue,SIGNED) = r.ednavalue
+                left join alertrule2 r on s.alertvalue = r.ednavalue
             </if>
             <if test="ruleType=='windturbine'">
                 left join warning2 r on s.alertvalue = r.ednavalue

+ 16 - 0
sample-kudu/src/main/java/com/gyee/wisdom/KuduSampleApplication.java

@@ -0,0 +1,16 @@
+package com.gyee.wisdom;
+
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+
+/**
+ * @description:
+ * @auther: Wanghs
+ * @date: 2022-11-21
+ */
+@SpringBootApplication
+public class KuduSampleApplication {
+    public static void main(String[] args) {
+        SpringApplication.run(KuduSampleApplication.class,args);
+    }
+}

+ 23 - 0
sample-kudu/src/main/java/com/gyee/wisdom/samplekudu/ApplicationReadyEventListener.java

@@ -0,0 +1,23 @@
+package com.gyee.wisdom.samplekudu;
+
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.context.event.ApplicationReadyEvent;
+import org.springframework.context.ApplicationListener;
+import org.springframework.stereotype.Component;
+
+@Component
+public class ApplicationReadyEventListener implements
+        ApplicationListener<ApplicationReadyEvent> {
+
+    @Autowired
+    private LcingCalc calculateServer;
+
+    @Override
+    public void onApplicationEvent(ApplicationReadyEvent event) {
+        System.out.println("ApplicationReadyEvent  rised!");
+        System.out.println("listener: " + event.toString());
+      //  calculateServer.start();
+    }
+
+}

+ 200 - 0
sample-kudu/src/main/java/com/gyee/wisdom/samplekudu/LcingCalc.java

@@ -0,0 +1,200 @@
+package com.gyee.wisdom.samplekudu;
+
+import com.google.common.collect.Lists;
+import com.google.common.util.concurrent.Futures;
+import com.google.common.util.concurrent.ListenableFuture;
+import com.google.common.util.concurrent.ListeningExecutorService;
+import com.google.common.util.concurrent.MoreExecutors;
+import com.gyee.wisdom.samplekudu.config.ConfigProperties;
+import com.gyee.wisdom.samplekudu.lcingcalc.CacheService;
+import com.gyee.wisdom.samplekudu.lcingcalc.LcingCalcTask;
+import com.gyee.wisdom.samplekudu.transport.RestfulClient;
+import com.gyee.wisdom.samplekudu.util.StringUtil;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.concurrent.Callable;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.TimeUnit;
+import java.util.stream.Collectors;
+
+import static java.lang.Thread.sleep;
+
+/**
+ * @description:
+ * @auther: Wanghs
+ * @date: 2022-12-09
+ */
+@Component
+@Slf4j
+public class LcingCalc {
+
+    //十分钟平均风速,功率,环境温度,状态,
+    //并网状态&&十分钟平均功率/十分钟平均风速对应的功率值<0.8 &&环境温度为-10度
+    //需算出 5,6,7,8,9,10,10,12,13,14,15m风分别对应的功率值
+    //超出15米以满发计算
+    private boolean serverStarted = false;
+    private boolean readThreadFlag = false;
+    private boolean calcThreadFlag = false;
+    //只有数据加载线程执行成功一次后,才开始执行计算线程
+    private boolean readRtdbSuccess = false;
+
+    @Autowired
+    private ConfigProperties configProperties;
+
+    @Autowired
+    private RestfulClient restfulClient;
+
+    @Autowired
+    private CacheService cacheService;
+
+
+    public boolean start() {
+
+        if (serverStarted) {
+            return true;
+        }
+        try {
+            //GlobalVar.config = configProperties;
+            log.warn("覆冰计算服务启动...... ");
+            log.info("开始加载配置及测点数据......");
+
+
+            cacheService.getTagInfoMap();
+            readThreadFlag = true;
+            getReadThread().start();
+            sleep(1000);
+            calcThreadFlag = true;
+            getCalcThread().start();
+
+            serverStarted = true;
+        } catch (Exception ex) {
+            serverStarted = false;
+            stop();
+            log.error(ex.getMessage());
+            return false;
+        }
+
+        return true;
+    }
+
+    public void stop() {
+        readThreadFlag = false;
+        calcThreadFlag = false;
+        serverStarted = false;
+        try {
+            Thread.sleep(5000);
+            //线程停止后,清空报警规则相关缓存
+
+        } catch (Exception ex) {
+        }
+    }
+
+    Thread getReadThread() {
+        return new Thread(new Runnable() {
+            public void run() {
+                log.info("数据加载线程启动...");
+                while (readThreadFlag) {
+                    try {
+                        List<String> collect = Arrays.stream(cacheService.getTagInfoMap().keySet().toArray()).map(s -> (String) s).collect(Collectors.toList());
+
+                        restfulClient.getLatest(StringUtil.join(collect, ","));
+                        System.out.print("*");
+                        if (cacheService.getReadRtdbSuccess() == false) {
+                            sleep(configProperties.getCalcThreadInterval());
+                            continue;
+                        } else {
+                            if (readRtdbSuccess == false) {
+                                sleep(configProperties.getReadThreadInterval() * 3);
+                                readRtdbSuccess = true;
+                            }
+                        }
+                    } catch (Exception ex) {
+                        log.error(ex.getMessage());
+                    }
+                    sleep(configProperties.getReadThreadInterval());
+                }
+            }
+        });
+    }
+
+    Thread getCalcThread() {
+        return new Thread(new Runnable() {
+            public void run() {
+                log.info("状态计算线程启动...");
+
+                ExecutorService pool = Executors.newFixedThreadPool(configProperties.getMaxThreadCount());
+                ListeningExecutorService executorService = MoreExecutors.listeningDecorator(pool);
+                List<LcingCalcTask> lcingCalcTasks = cacheService.getTaskList();
+
+                List<Task> taskList = new ArrayList<>();
+                for (LcingCalcTask lcingCalcTask :
+                        lcingCalcTasks) {
+                    Task task = new Task(lcingCalcTask);
+                    taskList.add(task);
+                }
+
+
+                while (calcThreadFlag) {
+                    List<ListenableFuture<Integer>> futures = Lists.newArrayList();
+                    if (readRtdbSuccess == false) {
+                        sleep(configProperties.getCalcThreadInterval());
+                        continue;
+                    }
+
+                    try {
+                        if (taskList != null && taskList.size() > 0) {
+                            for (Task task : taskList) {
+                                futures.add(executorService.submit(task));
+                            }
+                        }
+
+                        final ListenableFuture<List<Integer>> resultsFuture = Futures.successfulAsList(futures);
+                        try {//所有都执行完毕
+                            resultsFuture.get();
+                        } catch (Exception e) {
+                            e.printStackTrace();
+                        } finally {
+                            System.out.println("#");
+                        }
+                    } catch (Exception ex) {
+                        log.info(ex.getMessage());
+                    }
+                    System.out.println("#");
+                    sleep(configProperties.getCalcThreadInterval());
+                }
+
+                if (pool != null)
+                    pool.shutdown();
+            }
+        });
+    }
+
+    class Task implements Callable<Integer> {
+        private LcingCalcTask lcingCalcTask;
+
+        public Task(LcingCalcTask task) {
+            this.lcingCalcTask = task;
+        }
+
+        @Override
+        public Integer call() throws Exception {
+            lcingCalcTask.run();
+            System.out.print('.');
+            return 1;
+        }
+    }
+
+    private void sleep(int milliseconds) {
+        try {
+            TimeUnit.MILLISECONDS.sleep(milliseconds);
+        } catch (Exception ex) {
+            log.info(ex.getMessage());
+        }
+    }
+}

+ 45 - 0
sample-kudu/src/main/java/com/gyee/wisdom/samplekudu/advice/ControllerExecptionAdvice.java

@@ -0,0 +1,45 @@
+package com.gyee.wisdom.samplekudu.advice;
+
+import com.gyee.wisdom.samplekudu.exception.APIRunTimeException;
+import com.gyee.wisdom.samplekudu.util.ResultCode;
+import com.gyee.wisdom.samplekudu.util.ResultVo;
+import org.springframework.validation.BindException;
+import org.springframework.validation.ObjectError;
+import org.springframework.web.bind.MethodArgumentNotValidException;
+import org.springframework.web.bind.annotation.ExceptionHandler;
+import org.springframework.web.bind.annotation.ResponseBody;
+import org.springframework.web.bind.annotation.RestControllerAdvice;
+
+import java.util.stream.Collectors;
+
+@RestControllerAdvice
+public class ControllerExecptionAdvice {
+    //统一捕捉因参数校验不通过的异常
+    @ExceptionHandler({BindException.class, MethodArgumentNotValidException.class})
+    @ResponseBody
+    public ResultVo methodArgumentNotValidExceptionHandler(BindException e) {
+
+        ObjectError objectError = e.getBindingResult().getAllErrors().get(0);
+        String errorInfo = e.getBindingResult().getAllErrors().stream().map(m -> m.getDefaultMessage())
+                .collect(Collectors.joining(";", "", ""));
+        return new ResultVo(ResultCode.VALIDATE_ERROR,errorInfo);
+    }
+
+    //具体的自定义异常捕捉
+    @ExceptionHandler({APIRunTimeException.class})
+    @ResponseBody
+    public ResultVo methodRunExceptionHandler(APIRunTimeException e) {
+
+      return new ResultVo(ResultCode.FAILED.getCode(),e.getMessage(),e.getStackTrace());
+
+    }
+    //统一运行时的异常捕捉
+    @ExceptionHandler({RuntimeException.class})
+    @ResponseBody
+    public ResultVo runTimeExceptionHandler(RuntimeException e) {
+
+        return new ResultVo(ResultCode.FAILED.getCode(),e.getMessage(),e.getStackTrace());
+
+    }
+
+}

+ 42 - 0
sample-kudu/src/main/java/com/gyee/wisdom/samplekudu/advice/ControllerResponseAdvice.java

@@ -0,0 +1,42 @@
+package com.gyee.wisdom.samplekudu.advice;
+
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.gyee.wisdom.samplekudu.exception.APIException;
+import com.gyee.wisdom.samplekudu.util.ResultCode;
+import com.gyee.wisdom.samplekudu.util.ResultVo;
+import org.springframework.core.MethodParameter;
+import org.springframework.http.MediaType;
+import org.springframework.http.converter.HttpMessageConverter;
+import org.springframework.http.server.ServerHttpRequest;
+import org.springframework.http.server.ServerHttpResponse;
+import org.springframework.web.bind.annotation.RestControllerAdvice;
+import org.springframework.web.servlet.mvc.method.annotation.ResponseBodyAdvice;
+
+@RestControllerAdvice(basePackages = {"com.wanghs.cloud"})
+public class ControllerResponseAdvice implements ResponseBodyAdvice<Object> {
+    @Override
+    public boolean supports(MethodParameter methodParameter, Class<? extends HttpMessageConverter<?>> aClass) {
+        // response是ResultVo类型,或者注释了NotControllerResponseAdvice都不进行包装
+        return !(methodParameter.getParameterType().isAssignableFrom(ResultVo.class)
+                || methodParameter.hasMethodAnnotation(NotControllerResponseAdvice.class));
+    }
+
+    @Override
+    public Object beforeBodyWrite(Object body, MethodParameter returnType, MediaType selectedContentType, Class<? extends HttpMessageConverter<?>> selectedConverterType, ServerHttpRequest request, ServerHttpResponse response) {
+        // String类型不能直接包装
+        if (returnType.getGenericParameterType().equals(String.class)) {
+            ObjectMapper objectMapper = new ObjectMapper();
+            try {
+                // 将数据包装在ResultVo里后转换为json串进行返回
+                return objectMapper.writeValueAsString(new ResultVo(body));
+            } catch (JsonProcessingException e) {
+                throw new APIException(ResultCode.RESPONSE_PACK_ERROR, e.getMessage());
+            }
+        }
+        // 否则直接包装成ResultVo返回
+        return new ResultVo(body);
+    }
+
+
+}

+ 17 - 0
sample-kudu/src/main/java/com/gyee/wisdom/samplekudu/advice/NotControllerResponseAdvice.java

@@ -0,0 +1,17 @@
+package com.gyee.wisdom.samplekudu.advice;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * @description: 是否使用标准vo返回,如果在controller接口上添加@NotControllerResponseAdvice,则返回数据不会被Advice进行拦截包装成标中VO
+ * @auther: Wanghs
+ * @date: 2022-07-03
+ */
+@Target({ElementType.METHOD})
+@Retention(RetentionPolicy.RUNTIME)
+public @interface NotControllerResponseAdvice {
+}
+

+ 315 - 0
sample-kudu/src/main/java/com/gyee/wisdom/samplekudu/biz/LcingSampleImportBiz.java

@@ -0,0 +1,315 @@
+package com.gyee.wisdom.samplekudu.biz;
+
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.gyee.wisdom.samplekudu.domain.data.LcingTagNameData;
+import com.gyee.wisdom.samplekudu.entity.LcingSampleEntity;
+import com.gyee.wisdom.samplekudu.entity.TsPointEntity;
+import com.gyee.wisdom.samplekudu.domain.input.InputLcing;
+import com.gyee.wisdom.samplekudu.kudu.KuduConnection;
+import com.gyee.wisdom.samplekudu.service.TsPointService;
+import com.gyee.wisdom.samplekudu.taos.TaosHistoryDao;
+import com.gyee.wisdom.samplekudu.timeseries.BooleanTsData;
+import com.gyee.wisdom.samplekudu.timeseries.DoubleTsData;
+import com.gyee.wisdom.samplekudu.timeseries.TsData;
+import com.gyee.wisdom.samplekudu.util.CsvExportUtil;
+import com.gyee.wisdom.samplekudu.util.SnowflakeGenerator;
+import com.gyee.wisdom.samplekudu.util.StringUtil;
+import org.apache.commons.lang3.SerializationUtils;
+import org.apache.kudu.ColumnSchema;
+import org.apache.kudu.client.*;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.stereotype.Component;
+
+import java.io.OutputStream;
+import java.lang.reflect.Field;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.util.*;
+import java.util.stream.Collectors;
+
+import org.apache.kudu.client.KuduScanner.KuduScannerBuilder;
+
+/**
+ * @description:
+ * @auther: Wanghs
+ * @date: 2022-11-22
+ */
+@Component
+public class LcingSampleImportBiz {
+
+    @Value("${kudu_lcing_sample_table:impala::gyee_sample_kudu.lcing_sample}")
+    private String lcingSampleTableName;
+
+    @Autowired
+    private TsPointService tsPointService;
+
+    @Autowired
+    private TaosHistoryDao taosHistoryDao;
+
+    @Autowired
+    private KuduConnection kuduConnection;
+
+    //统一编码转化为具体测点数据
+    public LcingTagNameData initTagNameData(InputLcing lcing) throws IllegalAccessException, NoSuchMethodException, InvocationTargetException {
+        LcingTagNameData data = new LcingTagNameData();
+        Field[] lcingFieldArrays = lcing.getClass().getDeclaredFields();
+        for (Field field :
+                lcingFieldArrays) {
+            String name = field.getName();
+
+            if (name.contains("UniformCode")) {
+                String getMethodStr_lcing = "get" + name.substring(0, 1).toUpperCase() + name.substring(1);
+                Method getMethod_lcing = lcing.getClass().getMethod(getMethodStr_lcing);
+                String uniformCode = (String) getMethod_lcing.invoke(lcing);
+
+                List<TsPointEntity> pointList = tsPointService.getPointList(lcing.getWindturbineId(), Arrays.asList(uniformCode));
+
+                String setMethodStr_lcing = "set" + name.substring(0, 1).toUpperCase() + name.substring(1);
+                String setMethodStr_tagNameData = setMethodStr_lcing.replace("UniformCode", "TsPointEntity");
+                Method setMethod_tagNameData = data.getClass().getMethod(setMethodStr_tagNameData, Object.class);
+                setMethod_tagNameData.invoke(data, pointList.get(0));
+                System.out.println(field.getName());
+            } else {
+                String getMethodStr_lcing = "get" + name.substring(0, 1).toUpperCase() + name.substring(1);
+                Method getMethod_lcing = lcing.getClass().getMethod(getMethodStr_lcing);
+                Object fileVaue = getMethod_lcing.invoke(lcing);
+
+                String setMethodStr = "set" + name.substring(0, 1).toUpperCase() + name.substring(1);
+                Method setMethod_tagNameData = data.getClass().getMethod(setMethodStr, Object.class);
+                setMethod_tagNameData.invoke(data, fileVaue);
+
+            }
+        }
+
+        return data;
+    }
+
+    //包装样本数据
+    public List<LcingSampleEntity> importLcingSample(InputLcing inputLcing) throws Exception {
+
+        LcingTagNameData lcingTagNameData = initTagNameData(inputLcing);
+
+        Map<String, List<TsData>> taosHistoryDataMap = getTaosHistoryData(lcingTagNameData);
+
+
+        //针对taos中的时序数据进行清洗(主要是剔除状体不正常的数据,如有偏航动作,解缆动作,未处于并网状态等)
+        Map<String, List<TsData>> stringListMap = rejectData(taosHistoryDataMap);
+
+        //针对剔除后的数据进行包装(kudu)
+        List<LcingSampleEntity> entityList = initLcingSample(stringListMap, inputLcing.getWindturbineId(), inputLcing.getModel(), inputLcing.getStationId());
+
+        //TODO
+        //kudu写入操作
+
+        saveKudu(lcingSampleTableName, entityList, lcingTagNameData.getCorrectSample());
+        return entityList;
+
+    }
+
+    //根据清洗后的数据包装(kudu)
+    private List<LcingSampleEntity> initLcingSample(Map<String, List<TsData>> map, String windutbineId, String model, String stationId) throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
+
+
+        List<LcingSampleEntity> list = new ArrayList<>();
+        Object o = map.keySet().toArray()[0];
+        List<TsData> dataList = map.get(o);
+        for (int i = 0; i < dataList.size(); i++) {
+
+            LcingSampleEntity entity = new LcingSampleEntity();
+
+            entity.setWindturbineId(windutbineId).setModel(model).setStationId(stationId).setId(SnowflakeGenerator.generateId());
+            entity.setTs(dataList.get(i).getTs());
+
+            Field[] entityFieldArrays = entity.getClass().getDeclaredFields();
+
+            for (Field field :
+                    entityFieldArrays) {
+                String fieldName = field.getName();
+
+                if (fieldName.contains("Value") && !fieldName.contains("ts")) {
+                    String setMethodStr = "set" + fieldName.substring(0, 1).toUpperCase() + fieldName.substring(1);
+                    Method setMethod = entity.getClass().getMethod(setMethodStr, double.class);
+                    String key = fieldName + "TsPointEntity";
+                    if (map.containsKey(key.replace("Value", ""))) {
+                        List<TsData> otherDataList = map.get(key.replace("Value", ""));
+                        DoubleTsData doubleTsData = (DoubleTsData) otherDataList.get(i);
+                        setMethod.invoke(entity, doubleTsData.getDoubleValue());
+                    }
+                }
+
+            }
+            list.add(entity);
+
+        }
+
+        return list;
+
+    }
+
+    //获取历史时序数据
+    private Map<String, List<TsData>> getTaosHistoryData(LcingTagNameData lcingTagNameData) throws Exception {
+        Field[] lcingFieldArrays = lcingTagNameData.getClass().getDeclaredFields();
+
+        Map<String, List<TsData>> resultMap = new HashMap<>();
+
+        for (Field field :
+                lcingFieldArrays) {
+            String fieldName = field.getName();
+            if (fieldName.contains("TsPointEntity")) {
+                String getMethodStr_lcing = "get" + fieldName.substring(0, 1).toUpperCase() + fieldName.substring(1);
+                Method getMethod_lcing = lcingTagNameData.getClass().getMethod(getMethodStr_lcing);
+                TsPointEntity tsPointEntity = (TsPointEntity) getMethod_lcing.invoke(lcingTagNameData);
+
+                List<TsData> tsDataHistory = taosHistoryDao.getTsDataHistory(tsPointEntity.getId(), tsPointEntity.getDataType(), lcingTagNameData.getStartTime(), lcingTagNameData.getEndTime(), 1);
+                resultMap.put(fieldName, tsDataHistory);
+            }
+        }
+        return resultMap;
+    }
+
+    //数据清洗
+    private Map<String, List<TsData>> rejectData(Map<String, List<TsData>> map) {
+
+        //存储需要剔除的时间戳 剔除逻辑,偏航,解缆等动作为1,或风机状态不为并网
+        List<Long> rejectTime = new ArrayList<>();
+        for (Map.Entry<String, List<TsData>> entry :
+                map.entrySet()) {
+            if (entry.getValue().size() > 0) {
+                TsData tsData = entry.getValue().get(0);
+                if (tsData instanceof BooleanTsData) {
+                    if (entry.getKey().contains("Status")) {
+                        entry.getValue().forEach(s -> {
+                            BooleanTsData booleanTsData = (BooleanTsData) s;
+                            if (booleanTsData.getBooleanValue() == false) {
+                                rejectTime.add(booleanTsData.getTs());
+                            }
+                        });
+                    } else {
+                        entry.getValue().forEach(s -> {
+                            BooleanTsData booleanTsData = (BooleanTsData) s;
+                            if (booleanTsData.getBooleanValue() == true) {
+                                rejectTime.add(booleanTsData.getTs());
+                            }
+                        });
+                    }
+                }
+            }
+        }
+
+        Map<String, List<TsData>> resultMap = new HashMap<>();
+
+        for (Map.Entry<String, List<TsData>> entry :
+                map.entrySet()) {
+            List<TsData> collect = entry.getValue().stream().filter(s -> !rejectTime.contains(s.getTs())).collect(Collectors.toList());
+            resultMap.put(entry.getKey(), collect);
+
+        }
+        return resultMap;
+    }
+
+    private boolean saveKudu(String tableName, List<LcingSampleEntity> entityList, Boolean correctSample) throws KuduException, NoSuchMethodException, InvocationTargetException, IllegalAccessException {
+
+        KuduClient kuduClient = kuduConnection.getKuduClient();
+        KuduSession kuduSession = kuduClient.newSession();
+        kuduSession.setFlushMode(SessionConfiguration.FlushMode.AUTO_FLUSH_SYNC);
+        KuduTable lcingSampleTable = kuduClient.openTable(tableName);
+
+        for (LcingSampleEntity entity :
+                entityList) {
+
+            Insert insert = lcingSampleTable.newInsert();
+            PartialRow row = insert.getRow();
+            row.addBoolean("correct_sample", correctSample);
+
+            Field[] declaredFields = entity.getClass().getDeclaredFields();
+            for (Field field :
+                    declaredFields) {
+                TableField methodAnno = field.getAnnotation(TableField.class);
+                // 根据对象获取注解值
+                String infoFiledName = methodAnno.value();
+
+                String fieldName = field.getName();
+                String getMethodStr_lcing = "get" + fieldName.substring(0, 1).toUpperCase() + fieldName.substring(1);
+                Method getMethod_lcing = entity.getClass().getMethod(getMethodStr_lcing);
+                Object fileVaue = getMethod_lcing.invoke(entity);
+                if (fieldName == "id" || fieldName == "ts")
+                    row.addLong(infoFiledName, (Long) fileVaue);
+                else if (fieldName.contains("Value")) {
+                    row.addDouble(infoFiledName, (Double) fileVaue);
+                } else {
+                    row.addString(infoFiledName, fileVaue.toString());
+                }
+
+
+            }
+            kuduSession.apply(insert);
+            System.out.println("123");
+//            kuduSession.apply(insert);
+//            kuduSession.flush();
+        }
+
+
+        kuduSession.flush();
+
+        return true;
+    }
+
+    public List<LcingSampleEntity> getLcingSample(Boolean correct, Long startTs, Long endTs) throws KuduException {
+
+        KuduClient kuduClient = kuduConnection.getKuduClient();
+        KuduTable kuduTable = kuduClient.openTable(lcingSampleTableName);
+        KuduScannerBuilder kuduScannerBuilder = kuduClient.newScannerBuilder(kuduTable);
+
+
+        List<String> columnList = new ArrayList<>();
+        columnList.add("correct_sample");
+        for (Field field :
+                LcingSampleEntity.class.getDeclaredFields()) {
+
+            TableField methodAnno = field.getAnnotation(TableField.class);
+            // 根据对象获取注解值
+            String infoFiledName = methodAnno.value();
+            columnList.add(infoFiledName);
+        }
+
+        kuduScannerBuilder.setProjectedColumnNames(columnList);
+        if (correct != null) {
+            KuduPredicate predicate = KuduPredicate.newComparisonPredicate(kuduTable.getSchema().getColumn("correct_sample"), KuduPredicate.ComparisonOp.EQUAL, correct);
+            kuduScannerBuilder.addPredicate(predicate);
+        }
+        if (startTs != null) {
+            KuduPredicate predicate = KuduPredicate.newComparisonPredicate(kuduTable.getSchema().getColumn("ts"), KuduPredicate.ComparisonOp.GREATER_EQUAL, startTs);
+            kuduScannerBuilder.addPredicate(predicate);
+        }
+        if (endTs != null) {
+            KuduPredicate predicate = KuduPredicate.newComparisonPredicate(kuduTable.getSchema().getColumn("ts"), KuduPredicate.ComparisonOp.LESS_EQUAL, endTs);
+            kuduScannerBuilder.addPredicate(predicate);
+        }
+        KuduScanner scanner = kuduScannerBuilder.build();
+        while (scanner.hasMoreRows()) {
+            RowResultIterator results = scanner.nextRows();
+            // 每次从tablet中获取的数据的行数
+            int numRows = results.getNumRows();
+            List<Map<String,Object>>  lst=new ArrayList<>();
+            while (results.hasNext()) {
+
+                RowResult result = results.next();
+
+               Map<String,Object> mp=new HashMap<>();
+                for (String c:
+                     columnList) {
+                    Optional<ColumnSchema> first = result.getSchema().getColumns().stream().filter(s -> s.getName().equals(c)).findFirst();
+
+                    String str = result.getString(c);
+                    mp.put(c,str);
+                }
+                lst.add(mp);
+            }
+            System.out.println("--");
+
+        }
+        return null;
+    }
+
+}

+ 27 - 0
sample-kudu/src/main/java/com/gyee/wisdom/samplekudu/config/ConfigProperties.java

@@ -0,0 +1,27 @@
+package com.gyee.wisdom.samplekudu.config;
+
+import lombok.Data;
+import org.springframework.boot.context.properties.ConfigurationProperties;
+import org.springframework.stereotype.Component;
+
+@Data
+@Component
+@ConfigurationProperties("calculate.config")
+public class ConfigProperties {
+
+    //数据适配器websocket服务地址
+    private String serviceUrl;
+
+    //报警分表数据服务地址
+    private String shardingServiceUrl;
+
+    //扫描实时数据线程轮询时间间隔,单位毫秒
+    private int readThreadInterval = 1000;
+
+    //计算状态线程轮询时间间隔,单位毫秒
+    private int calcThreadInterval = 100;
+
+    //规则解析线程池大小
+    private int maxThreadCount = 4;
+
+}

+ 69 - 0
sample-kudu/src/main/java/com/gyee/wisdom/samplekudu/controller/LcingSampleController.java

@@ -0,0 +1,69 @@
+package com.gyee.wisdom.samplekudu.controller;
+
+import com.gyee.wisdom.samplekudu.biz.LcingSampleImportBiz;
+import com.gyee.wisdom.samplekudu.domain.input.InputLcing;
+import com.gyee.wisdom.samplekudu.entity.LcingSampleEntity;
+import com.gyee.wisdom.samplekudu.util.CsvExportUtil;
+import io.swagger.v3.oas.annotations.Operation;
+import io.swagger.v3.oas.annotations.Parameter;
+import io.swagger.v3.oas.annotations.tags.Tag;
+import org.apache.kudu.client.KuduException;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.*;
+
+import javax.servlet.http.HttpServletResponse;
+import java.io.OutputStream;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * @description:
+ * @auther: Wanghs
+ * @date: 2022-11-22
+ */
+@RestController
+@RequestMapping("/lcing")
+@Tag(name = "样本数据导入")
+public class LcingSampleController {
+
+    @Autowired
+    private LcingSampleImportBiz lcingSampleImportBiz;
+
+    @PostMapping("/import")
+    @Operation(description = "根据参数信息从时序数据库提取数据到kudu")
+    public String importLcingSample(HttpServletResponse response, @RequestBody @Validated InputLcing lcing) throws Exception {
+
+        List<LcingSampleEntity> entityList = lcingSampleImportBiz.importLcingSample(lcing);
+        OutputStream outputStream = null;
+        try {
+            CsvExportUtil.responseSetProperties("覆冰样本数据", response);
+            outputStream = response.getOutputStream();
+
+            CsvExportUtil.doExport(entityList, null, outputStream);
+        } catch (Exception ex) {
+            ex.printStackTrace();
+        } finally {
+            if (outputStream != null) {
+                outputStream.close();
+            }
+        }
+
+
+        return "123";
+
+    }
+    @Operation(description = "从kudu中获取样本数据")
+    @GetMapping("/get")
+    public List<LcingSampleEntity> getLcingSample(@Parameter(  name ="correct",description = "是否为正样本")@RequestParam(value = "correct",required = false)Boolean correct,
+                                                  @Parameter(  name ="startTs",description = "开始时间")@RequestParam(value = "startTs",required = false)Long startTs,
+                                                  @Parameter(  name ="endTs",description = "结束时间")@RequestParam(value = "endTs",required = false)Long endTs) throws KuduException {
+        lcingSampleImportBiz.getLcingSample(correct,startTs,endTs);
+        return new ArrayList<>();
+    }
+
+    @GetMapping("/test")
+    public String test(@Parameter(name = "name", required = true) String name) {
+        return name + "123";
+    }
+}

+ 143 - 0
sample-kudu/src/main/java/com/gyee/wisdom/samplekudu/domain/data/LcingTagNameData.java

@@ -0,0 +1,143 @@
+package com.gyee.wisdom.samplekudu.domain.data;
+
+import com.gyee.wisdom.samplekudu.entity.TsPointEntity;
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+
+import javax.validation.constraints.NotNull;
+import java.io.Serializable;
+
+/**
+ * @description:
+ * @auther: Wanghs
+ * @date: 2022-11-22
+ */
+@Data
+public class LcingTagNameData implements Serializable {
+
+    private String windturbineId;
+
+    private String stationId;
+
+    private String model;
+
+    private TsPointEntity windSpeedTsPointEntity;
+
+    private TsPointEntity impellerSpeedTsPointEntity;
+
+    private TsPointEntity bladeAngle1TsPointEntity;
+
+    private TsPointEntity bladeAngle2TsPointEntity;
+
+    private TsPointEntity bladeAngle3TsPointEntity;
+
+    private TsPointEntity yawDeviationTsPointEntity;
+
+    private TsPointEntity powerTsPointEntity;
+
+    private TsPointEntity torqueTsPointEntity;
+
+    private TsPointEntity windDirectionTsPointEntity;
+
+    private TsPointEntity roomPositionTsPointEntity;
+
+    private TsPointEntity untwistTsPointEntity;
+
+    private TsPointEntity leftYawTsPointEntity;
+
+    private TsPointEntity rightYawTsPointEntity;
+
+    private  TsPointEntity windturbineStatusTsPointEntity;
+
+    private TsPointEntity limitPowerTsPointEntity;
+
+    private Boolean correctSample;
+
+    private Long startTime;
+
+    private Long endTime;
+
+    public void setWindturbineId(Object windturbineId) {
+        this.windturbineId = (String) windturbineId;
+    }
+
+    public void setStationId(Object stationId) {
+        this.stationId = (String) stationId;
+    }
+
+    public void setModel(Object model) {
+        this.model = (String) model;
+    }
+
+
+    public void setWindSpeedTsPointEntity(Object windSpeedTsPointEntity) {
+        this.windSpeedTsPointEntity = (TsPointEntity)windSpeedTsPointEntity;
+    }
+
+    public void setImpellerSpeedTsPointEntity(Object impellerSpeedTsPointEntity) {
+        this.impellerSpeedTsPointEntity = (TsPointEntity)impellerSpeedTsPointEntity;
+    }
+
+    public void setBladeAngle1TsPointEntity(Object bladeAngle1TsPointEntity) {
+        this.bladeAngle1TsPointEntity = (TsPointEntity)bladeAngle1TsPointEntity;
+    }
+
+    public void setBladeAngle2TsPointEntity(Object bladeAngle2TsPointEntity) {
+        this.bladeAngle2TsPointEntity = (TsPointEntity)bladeAngle2TsPointEntity;
+    }
+
+    public void setBladeAngle3TsPointEntity(Object bladeAngle3TsPointEntity) {
+        this.bladeAngle3TsPointEntity = (TsPointEntity)bladeAngle3TsPointEntity;
+    }
+
+    public void setYawDeviationTsPointEntity(Object yawDeviationTsPointEntity) {
+        this.yawDeviationTsPointEntity = (TsPointEntity)yawDeviationTsPointEntity;
+    }
+
+    public void setPowerTsPointEntity(Object powerTsPointEntity) {
+        this.powerTsPointEntity = (TsPointEntity)powerTsPointEntity;
+    }
+
+    public void setTorqueTsPointEntity(Object torqueTsPointEntity) {
+        this.torqueTsPointEntity =(TsPointEntity) torqueTsPointEntity;
+    }
+
+    public void setWindDirectionTsPointEntity(Object windDirectionTsPointEntity) {
+        this.windDirectionTsPointEntity =(TsPointEntity) windDirectionTsPointEntity;
+    }
+
+    public void setRoomPositionTsPointEntity(Object roomPositionTsPointEntity) {
+        this.roomPositionTsPointEntity = (TsPointEntity)roomPositionTsPointEntity;
+    }
+
+    public void setUntwistTsPointEntity(Object untwistTsPointEntity) {
+        this.untwistTsPointEntity =(TsPointEntity) untwistTsPointEntity;
+    }
+
+    public void setLeftYawTsPointEntity(Object leftYawTsPointEntity) {
+        this.leftYawTsPointEntity = (TsPointEntity)leftYawTsPointEntity;
+    }
+
+    public void setRightYawTsPointEntity(Object rightYawTsPointEntity) {
+        this.rightYawTsPointEntity = (TsPointEntity)rightYawTsPointEntity;
+    }
+
+    public void setWindturbineStatusTsPointEntity(Object windturbineStatusTsPointEntity) {
+        this.windturbineStatusTsPointEntity = (TsPointEntity)windturbineStatusTsPointEntity;
+    }
+
+    public void setLimitPowerTsPointEntity( Object limitPowerTsPointEntity) {
+        this.limitPowerTsPointEntity = (TsPointEntity)limitPowerTsPointEntity;
+    }
+    public void setStartTime(Object startTime) {
+        this.startTime =(Long) startTime;
+    }
+
+    public void setEndTime(Object endTime) {
+        this.endTime = (Long)endTime;
+    }
+
+    public void setCorrectSample(Object correctSample) {
+        this.correctSample = (Boolean)correctSample;
+    }
+}

+ 103 - 0
sample-kudu/src/main/java/com/gyee/wisdom/samplekudu/domain/input/InputLcing.java

@@ -0,0 +1,103 @@
+package com.gyee.wisdom.samplekudu.domain.input;
+
+import com.gyee.wisdom.samplekudu.entity.TsPointEntity;
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+
+import javax.validation.constraints.NotBlank;
+import javax.validation.constraints.NotNull;
+import java.io.Serializable;
+
+/**
+ * @description: 覆冰数据提取参数
+ * @auther: Wanghs
+ * @date: 2022-11-22
+ */
+@Data
+@Schema(name = "InputLcing", description = "叶片覆冰数据导入通用参数")
+public class InputLcing implements Serializable {
+
+    @NotBlank
+    @Schema(name = "windturbineId", description = "风机编号")
+    private String windturbineId;
+
+    @NotBlank
+    @Schema(name = "stationId", description = "风场id")
+    private String stationId;
+
+    @NotBlank
+    @Schema(name = "model", description = "风机型号")
+    private String model;
+
+    @NotBlank
+    @Schema(name = "windSpeedUniformCode", description = "风速统一编码")
+    private String windSpeedUniformCode;
+
+    @NotBlank
+    @Schema(name = "impellerSpeedUniformCode", description = "叶轮转速统一编码")
+    private String impellerSpeedUniformCode;
+
+    @NotBlank
+    @Schema(name = "bladeAngle1UniformCode", description = "桨距角1统一编码")
+    private String bladeAngle1UniformCode;
+
+    @NotBlank
+    @Schema(name = "bladeAngle2UniformCode", description = "桨距角2统一编码")
+    private String bladeAngle2UniformCode;
+
+    @NotBlank
+    @Schema(name = "bladeAngle3UniformCode", description = "桨距角3统一编码")
+    private String bladeAngle3UniformCode;
+
+    @NotBlank
+    @Schema(name = "yawDeviationUniformCode", description = "偏航误差统一编码")
+    private String yawDeviationUniformCode;
+
+    @NotBlank
+    @Schema(name = "powerUniformCode", description = "功率统一编码")
+    private String powerUniformCode;
+
+    @NotBlank
+    @Schema(name = "torqueUniformCode", description = "转矩统一编码")
+    private String torqueUniformCode;
+
+    @NotBlank
+    @Schema(name = "windDirectionUniformCode", description = "风向统一编码")
+    private String windDirectionUniformCode;
+
+    @NotBlank
+    @Schema(name = "roomPositionUniformCode", description = "机舱位置统一编码")
+    private String roomPositionUniformCode;
+
+    @NotBlank
+    @Schema(name = "untwistUniformCode", description = "解缆动作统一编码")
+    private String untwistUniformCode;
+
+    @NotBlank
+    @Schema(name = "leftYawUniformCode", description = "左偏航统一编码")
+    private String leftYawUniformCode;
+
+    @NotBlank
+    @Schema(name = "rightYawUniformCode", description = "右偏航统一编码")
+    private String rightYawUniformCode;
+
+    @NotBlank
+    @Schema(name = "windturbineStatusUniformCode", description = "风机状态统一编码")
+    private  String windturbineStatusUniformCode;
+
+    @NotBlank
+    @Schema(name = "limitPowerUniformCode", description = "限电状态统一编码")
+    private String limitPowerUniformCode;
+
+    @NotNull
+    @Schema(name = "correctSample", description = "是否为正样本")
+    private Boolean correctSample;
+
+    @NotNull
+    @Schema(name = "startTime", description = "样本提取开始时间")
+    private Long startTime;
+
+    @NotNull
+    @Schema(name = "endTime", description = "样本提取结束时间")
+    private Long endTime;
+}

+ 64 - 0
sample-kudu/src/main/java/com/gyee/wisdom/samplekudu/entity/LcingSampleEntity.java

@@ -0,0 +1,64 @@
+package com.gyee.wisdom.samplekudu.entity;
+
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import lombok.Data;
+import lombok.experimental.Accessors;
+
+import java.io.Serializable;
+
+/**
+ * @description:
+ * @auther: Wanghs
+ * @date: 2022-11-23
+ */
+@Data
+@Accessors(chain = true)
+@TableName("lcing_sample")
+public class LcingSampleEntity implements Serializable {
+    @TableField("id")
+    private Long id;
+
+    @TableField("station_id")
+    private String stationId;
+
+    @TableField("windturbine_id")
+    private String windturbineId;
+
+    @TableField("model")
+    private String model;
+
+    @TableField("wind_speed")
+    private double windSpeedValue;
+
+    @TableField("impeller_speed")
+    private double impellerSpeedValue;
+
+    @TableField("blade_angle1")
+    private double bladeAngle1Value;
+
+    @TableField("blade_angle2")
+    private double bladeAngle2Value;
+
+    @TableField("blade_angle3")
+    private double bladeAngle3Value;
+
+    @TableField("yaw_deviation")
+    private double yawDeviationValue;
+
+    @TableField("power")
+    private double powerValue;
+
+    @TableField("torque")
+    private double torqueValue;
+
+    @TableField("wind_direction")
+    private double windDirectionValue;
+
+    @TableField("room_position")
+    private double roomPositionValue;
+
+    @TableField("ts")
+    private Long ts;
+}

+ 64 - 0
sample-kudu/src/main/java/com/gyee/wisdom/samplekudu/entity/TsPointEntity.java

@@ -0,0 +1,64 @@
+package com.gyee.wisdom.samplekudu.entity;
+
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableName;
+import com.gyee.wisdom.samplekudu.timeseries.BasicTsPoint;
+import com.gyee.wisdom.samplekudu.timeseries.TsDataType;
+import com.gyee.wisdom.samplekudu.timeseries.TsPoint;
+import lombok.Data;
+
+import java.io.Serializable;
+
+/**
+ * @description:
+ * @auther: Wanghs
+ * @date: 2022-11-22
+ */
+@Data
+@TableName("view_tspoint")
+public class TsPointEntity implements Serializable {
+
+
+    @TableField("ID")
+    private String id;
+    /**
+     * 设备类型
+     */
+   @TableField("THING_TYPE")
+    private String thingType;
+    /**
+     * 设备Id
+     */
+    @TableField("THING_ID")
+    private String thingId;
+    /**
+     * 统一编码
+     */
+    @TableField("UNIFORM_CODE")
+    private String uniformCode;
+    /**
+     * 点类型
+     */
+    @TableField("DATA_TYPE")
+    private String dataType;
+
+
+    public TsPoint toData() {
+        TsDataType tsDataType = TsDataType.DOUBLE;
+        if ("bool".equals(this.dataType))
+            tsDataType = TsDataType.BOOLEAN;
+        else if (this.dataType == null)
+            tsDataType = TsDataType.DOUBLE;
+        else if (this.dataType.contains("INT"))
+            tsDataType = TsDataType.LONG;
+
+        BasicTsPoint data = new BasicTsPoint(this.id, tsDataType);
+        if (!"".equals(thingId))
+            data.setThingId(this.thingId);
+        if (!"".equals(thingType))
+            data.setThingType(this.thingType);
+        if (!"".equals(uniformCode))
+            data.setUniformCode(this.uniformCode);
+        return data;
+    }
+}

+ 35 - 0
sample-kudu/src/main/java/com/gyee/wisdom/samplekudu/entity/WindturbineEntity.java

@@ -0,0 +1,35 @@
+package com.gyee.wisdom.samplekudu.entity;
+
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableName;
+import lombok.Data;
+
+import java.io.Serializable;
+
+/**
+ * @description:
+ * @auther: Wanghs
+ * @date: 2022-12-09
+ */
+@Data
+@TableName("windturbine")
+public class WindturbineEntity implements Serializable {
+
+    private String id;
+    private String code;
+    private String windpowerstationid;
+    private Double longitude;
+    private Double latitude;
+    private String modelid;
+    private String status;
+    private String projectid;
+    private String lineid;
+    private String firstintegratedtime;
+    private String photo;
+    private String name;
+    private String standardid;
+
+    public String getWindturbineCode(){
+        return this.code;
+    }
+}

+ 30 - 0
sample-kudu/src/main/java/com/gyee/wisdom/samplekudu/exception/APIException.java

@@ -0,0 +1,30 @@
+package com.gyee.wisdom.samplekudu.exception;
+
+import com.gyee.wisdom.samplekudu.util.AppCode;
+import com.gyee.wisdom.samplekudu.util.StatusCode;
+import lombok.Getter;
+
+@Getter
+public class APIException extends RuntimeException {
+    private int code;
+    private String msg;
+
+    // 手动设置异常
+    public APIException(StatusCode statusCode, String message) {
+        // message用于用户设置抛出错误详情,例如:当前价格-5,小于0
+        super(message);
+        // 状态码
+        this.code = statusCode.getCode();
+        // 状态码配套的msg
+        this.msg = statusCode.getMsg();
+    }
+
+    // 默认异常使用APP_ERROR状态码
+    public APIException(String message) {
+        super(message);
+        this.code = AppCode.APP_ERROR.getCode();
+        this.msg = AppCode.APP_ERROR.getMsg();
+    }
+
+}
+

+ 39 - 0
sample-kudu/src/main/java/com/gyee/wisdom/samplekudu/exception/APIRunTimeException.java

@@ -0,0 +1,39 @@
+package com.gyee.wisdom.samplekudu.exception;
+
+import com.gyee.wisdom.samplekudu.util.AppCode;
+import com.gyee.wisdom.samplekudu.util.StatusCode;
+import lombok.Getter;
+
+@Getter
+public class APIRunTimeException extends RuntimeException {
+    private int code;
+    private String msg;
+    private StackTraceElement[] stackTrace;
+
+
+    // 手动设置异常
+    public APIRunTimeException(StatusCode statusCode, String message, StackTraceElement[] stackTrace) {
+        // message用于用户设置抛出错误详情,例如:当前价格-5,小于0
+        super(message);
+        // 状态码
+        this.code = statusCode.getCode();
+        // 状态码配套的msg
+        this.msg = statusCode.getMsg();
+        //stack信息
+        this.stackTrace=stackTrace;
+    }
+
+    // 默认异常使用APP_ERROR状态码
+    public APIRunTimeException(String message,StackTraceElement[] stackTrace) {
+        super(message);
+        this.code = AppCode.APP_ERROR.getCode();
+        this.msg = AppCode.APP_ERROR.getMsg();
+        this.stackTrace=stackTrace;
+    }
+    // 默认异常使用APP_ERROR状态码
+    public APIRunTimeException(String message) {
+        super(message);
+        this.code = AppCode.APP_ERROR.getCode();
+        this.msg = AppCode.APP_ERROR.getMsg();
+    }
+}

+ 30 - 0
sample-kudu/src/main/java/com/gyee/wisdom/samplekudu/exception/TaosRunException.java

@@ -0,0 +1,30 @@
+package com.gyee.wisdom.samplekudu.exception;
+
+import com.gyee.wisdom.samplekudu.util.AppCode;
+import com.gyee.wisdom.samplekudu.util.StatusCode;
+
+/**
+ * @description:
+ * @auther: Wanghs
+ * @date: 2022-11-23
+ */
+public class TaosRunException extends RuntimeException  {
+
+    private int code;
+    private String msg;
+    private StackTraceElement[] stackTrace;
+
+
+    // 手动设置异常
+    public TaosRunException(StatusCode statusCode, String message, StackTraceElement[] stackTrace) {
+        // message用于用户设置抛出错误详情,例如:当前价格-5,小于0
+        super(message);
+        // 状态码
+        this.code = statusCode.getCode();
+        // 状态码配套的msg
+        this.msg = statusCode.getMsg();
+        //stack信息
+        this.stackTrace=stackTrace;
+    }
+
+}

+ 28 - 0
sample-kudu/src/main/java/com/gyee/wisdom/samplekudu/kudu/KuduConnection.java

@@ -0,0 +1,28 @@
+package com.gyee.wisdom.samplekudu.kudu;
+
+import org.apache.kudu.client.KuduClient;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.stereotype.Component;
+
+/**
+ * @description:
+ * @auther: Wanghs
+ * @date: 2022-12-06
+ */
+@Component
+public class KuduConnection {
+    @Value("${kudu_master:manager1.prd.nxd1.com,21050}")
+    private String kuduMaster;
+
+    private KuduClient kuduClient;
+
+
+    public KuduClient getKuduClient(){
+        if(kuduClient==null){
+            KuduClient.KuduClientBuilder kuduClientBuilder = new KuduClient.KuduClientBuilder(kuduMaster);
+            kuduClientBuilder.defaultSocketReadTimeoutMs(30000);
+            kuduClient = kuduClientBuilder.build();
+        }
+        return kuduClient;
+    }
+}

+ 103 - 0
sample-kudu/src/main/java/com/gyee/wisdom/samplekudu/lcingcalc/CacheService.java

@@ -0,0 +1,103 @@
+package com.gyee.wisdom.samplekudu.lcingcalc;
+
+import com.gyee.wisdom.samplekudu.entity.TsPointEntity;
+import com.gyee.wisdom.samplekudu.entity.WindturbineEntity;
+import com.gyee.wisdom.samplekudu.service.TsPointService;
+import com.gyee.wisdom.samplekudu.service.WindturbineService;
+import com.gyee.wisdom.samplekudu.timeseries.TsPoint;
+import lombok.Synchronized;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.stereotype.Service;
+import org.springframework.validation.annotation.Validated;
+
+import java.util.*;
+import java.util.stream.Collectors;
+
+@Slf4j
+@Service
+public class CacheService {
+
+    @Value("${lcing.station_id:XS_FDC}")
+    private String stationId;
+
+    @Value("${lcing.uniformcodes.UP97:AI007,AI128}")
+    private String uniformCodes_UP97;
+    @Value("${lcing.uniformcodes.UP105:AI007,AI128}")
+    private String uniformCodes_UP105;
+    @Value("${lcing.calc_cycle:600}")
+    private int lcing_calcCycle;
+
+    //标示读取实时数据的线程是否取得到了数据
+    private boolean readRtdbSuccess;
+
+    //key为具体测点,value为测点值
+    private Map<String, TagInfo> dataMap = new HashMap<>();
+
+    private List<LcingCalcTask> taskList = new ArrayList<>();
+
+    @Autowired
+    private WindturbineService windturbineService;
+
+    @Autowired
+    private TsPointService tsPointService;
+
+
+
+    public boolean getReadRtdbSuccess() {
+        return readRtdbSuccess;
+    }
+
+    public void setReadRtdbSuccess(boolean value) {
+        readRtdbSuccess = value;
+    }
+
+
+    public Map<String, TagInfo> getTagInfoMap() {
+        if (dataMap.size() <= 0)
+            createTagMap();
+        return this.dataMap;
+    }
+
+    @Synchronized
+    private void createTagMap() {
+        List<WindturbineEntity> windturbineEntityList = windturbineService.getWindturbine(stationId);
+        windturbineEntityList=   windturbineEntityList.stream().filter(s->s.getId().equals("XG01_01")).collect(Collectors.toList());
+        for (WindturbineEntity windturbine :
+                windturbineEntityList) {
+
+            List<String> uniformCodeList_UP97 = Arrays.asList(uniformCodes_UP97.split(","));
+            List<String> uniformCodeList_UP105 = Arrays.asList(uniformCodes_UP105.split(","));
+            List<TsPointEntity> pointList = null;
+            if (windturbine.getModelid().contains("97")) {
+                pointList = tsPointService.getPointList(windturbine.getId(), uniformCodeList_UP97);
+            } else {
+                pointList = tsPointService.getPointList(windturbine.getId(), uniformCodeList_UP105);
+            }
+
+            LcingCalcTask task = new LcingCalcTask(windturbine.getId(),lcing_calcCycle);
+            task.setStationId(windturbine.getWindpowerstationid());
+            task.setWindturbineId(windturbine.getId());
+            task.setModel(windturbine.getModelid());
+
+            Map<String, String> mp = new HashMap<>();
+            for (TsPointEntity pointEntity :
+                    pointList) {
+                mp.put(pointEntity.getUniformCode(), pointEntity.getId());
+                if (!dataMap.containsKey(pointEntity.getId())) {
+                    dataMap.put(pointEntity.getId(), new TagInfo(pointEntity.toData()));
+                }
+            }
+            task.setMap(mp);
+            taskList.add(task);
+        }
+    }
+
+    public List<LcingCalcTask> getTaskList(){
+        if(taskList.size()<=0)
+            createTagMap();
+        return taskList;
+    }
+
+}

+ 322 - 0
sample-kudu/src/main/java/com/gyee/wisdom/samplekudu/lcingcalc/LcingCalcTask.java

@@ -0,0 +1,322 @@
+package com.gyee.wisdom.samplekudu.lcingcalc;
+
+import com.gyee.wisdom.samplekudu.transport.AlarmSnap;
+import com.gyee.wisdom.samplekudu.transport.RemoteServiceBuilder;
+import com.gyee.wisdom.samplekudu.util.DateUtils;
+import com.gyee.wisdom.samplekudu.util.SpringContextUtil;
+import lombok.Data;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.lang3.StringUtils;
+
+import java.util.*;
+import java.util.concurrent.Callable;
+import java.util.stream.Collectors;
+
+/**
+ * @description:
+ * @auther: Wanghs
+ * @date: 2022-12-09
+ */
+@Data
+@Slf4j
+public class LcingCalcTask {
+
+    //风机编号
+    private String windturbineId;
+    //场站id
+    private String stationId;
+    //风机型号
+    private String model;
+    //计算周期
+    private int calcCycle;
+
+    private CacheService cacheService = SpringContextUtil.getBean(CacheService.class);
+
+    private RemoteServiceBuilder remoteServiceBuilder = SpringContextUtil.getBean(RemoteServiceBuilder.class);
+
+    //alertvalue=320003
+    private AlarmSnap alarmsnap_lcing_high;
+
+    //alertvalue=320002
+    private AlarmSnap alarmsnap_lcing_mid;
+
+    //alertvalue=320001
+    private AlarmSnap alarmsnap_lcing_lower;
+    //上一次覆冰计算时间
+    private Date lastCalcTime;
+
+
+    //key为统一编码,value  为具体测点
+    private Map<String, String> map = new HashMap<>();
+
+    private List<TriggerScore> scoreList = new ArrayList<>();
+
+    public LcingCalcTask(String windturbineId, int calcCycle) {
+        this.windturbineId = windturbineId;
+        this.calcCycle = calcCycle;
+        initAlarmSnap();
+    }
+
+
+    private void initAlarmSnap() {
+        AlarmSnap alertsnap_high = findAlertSnap(windturbineId, 320003);
+        AlarmSnap alertsnap_mid = findAlertSnap(windturbineId, 320002);
+        AlarmSnap alertsnap_lower = findAlertSnap(windturbineId, 320001);
+
+        if (alertsnap_high == null) {
+            alertsnap_high = new AlarmSnap();
+            //snap.setId(StringUtil.getUUID());
+            alertsnap_high.setAlertText("高级叶片覆冰风险");
+            alertsnap_high.setAlertValue(320003);
+            alertsnap_high.setProjectId("");
+            alertsnap_high.setCategory1("custom");
+            alertsnap_high.setCategory2("yp");
+            //如果报警规则的关联部件不为空
+            alertsnap_high.setCategory3("");
+            alertsnap_high.setRank("4");
+            alertsnap_high.setLastUpdateTime(new Date());
+            alertsnap_high.setIsOpened(0);
+        }
+        if (alertsnap_mid == null) {
+            alertsnap_mid = new AlarmSnap();
+            //snap.setId(StringUtil.getUUID());
+            alertsnap_mid.setAlertText("中级叶片覆冰风险");
+            alertsnap_mid.setAlertValue(320002);
+            alertsnap_mid.setProjectId("");
+            alertsnap_mid.setCategory1("custom");
+            alertsnap_mid.setCategory2("yp");
+            //如果报警规则的关联部件不为空
+            alertsnap_mid.setCategory3("");
+            alertsnap_mid.setRank("4");
+            alertsnap_mid.setLastUpdateTime(new Date());
+            alertsnap_mid.setIsOpened(0);
+        }
+        if (alertsnap_lower == null) {
+            alertsnap_lower = new AlarmSnap();
+            //snap.setId(StringUtil.getUUID());
+            alertsnap_lower.setAlertText("低级叶片覆冰风险");
+            alertsnap_lower.setAlertValue(320001);
+            alertsnap_lower.setProjectId("");
+            alertsnap_lower.setCategory1("custom");
+            alertsnap_lower.setCategory2("yp");
+            //如果报警规则的关联部件不为空
+            alertsnap_lower.setCategory3("");
+            alertsnap_lower.setRank("4");
+            alertsnap_lower.setLastUpdateTime(new Date());
+            alertsnap_lower.setIsOpened(0);
+        }
+        this.alarmsnap_lcing_high = alertsnap_high;
+        this.alarmsnap_lcing_mid = alertsnap_mid;
+        this.alarmsnap_lcing_lower = alertsnap_lower;
+
+    }
+
+    private AlarmSnap findAlertSnap(String thingId, int alertValue) {
+        RemoteServiceBuilder bean = SpringContextUtil.getBean(RemoteServiceBuilder.class);
+        try {
+            AlarmSnap alarmSnap = bean.alarmSnapService().queryOneByWtId(thingId, alertValue);
+            return alarmSnap;
+        } catch (Exception ex) {
+            log.warn(String.format("thingId=%s, alertValue=%d", thingId, alertValue));
+            log.error(ex.getMessage(), ex);
+            return null;
+        }
+
+    }
+
+
+    //解析规则
+    public void run() {
+
+        String windSpeedUnifomCode;
+        String temperatureUnifomCode;
+        String powerUniformCode;
+        String ztUnifomCode;
+        String theoryPowerUiformCode;
+
+        if (this.model.equals("UP97")) {
+            windSpeedUnifomCode = "AI025";
+            temperatureUnifomCode = "AI056";
+            powerUniformCode = "AI130";
+            ztUnifomCode = "DI058";
+            theoryPowerUiformCode = "LLGL";
+        } else {
+            windSpeedUnifomCode = "AI372";
+            temperatureUnifomCode = "AI056";
+            powerUniformCode = "AI130";
+            ztUnifomCode = "DI1885";
+            theoryPowerUiformCode = "LLGL";
+        }
+
+        TagInfo windSpeed = cacheService.getTagInfoMap().get(map.get(windSpeedUnifomCode));
+        TagInfo temperature = cacheService.getTagInfoMap().get(map.get(temperatureUnifomCode));
+        TagInfo power = cacheService.getTagInfoMap().get(map.get(powerUniformCode));
+        TagInfo zt = cacheService.getTagInfoMap().get(map.get(ztUnifomCode));
+        TagInfo theoryPower = cacheService.getTagInfoMap().get(map.get(theoryPowerUiformCode));
+
+        //计算逻辑
+        //根据实时风速找到理论功率,通过实际功率和理论功率差,如果超出一定的比例 如20%,则进行记录,
+        //超出的持续时间大于10分钟,则触发报警,并初步定位为叶片覆冰
+
+        //如果当前风机状态为并网,舱外温度为-10度,
+
+        //欠发功率比例  (理论功率-实际功率)/理论功率
+        double lackPowerPencent = (theoryPower.getDoubleTsData().getDoubleValue() - power.getDoubleTsData().getDoubleValue()) / theoryPower.getDoubleTsData().getDoubleValue();
+
+        System.out.println(
+                "风速:" + windSpeed.getDoubleTsData().getDoubleValue() +
+                        "---环境温度:" + temperature.getDoubleTsData().getDoubleValue() +
+                        "---理论功率:" + theoryPower.getDoubleTsData().getDoubleValue()
+                        + "---实际功率:" + power.getDoubleTsData().getDoubleValue() + "---欠发比例:" + lackPowerPencent
+        );
+
+        //当前为发电状态,且舱外温度小于10度,
+        //欠发比例大于20%,小于30%,判定为覆冰初期状态
+        //欠发比例大于30%,小于40%,判定为覆冰中期状态
+        //欠发比例大于40%,判定为覆冰后期状态
+        if (zt.getBooleanTsData().getBooleanValue() && temperature.getDoubleTsData().getDoubleValue() < -5.0) {
+            if (lackPowerPencent > 0.2 && lackPowerPencent <= 0.3) {
+
+                TriggerScore score = new TriggerScore(new Date(), 1);
+                lcingCheck(score);
+            } else if (lackPowerPencent > 0.3 && lackPowerPencent <= 0.4) {
+                TriggerScore score = new TriggerScore(new Date(), 2);
+                lcingCheck(score);
+            } else if (lackPowerPencent > 0.4) {
+                TriggerScore score = new TriggerScore(new Date(), 3);
+                lcingCheck(score);
+            } else {
+                //没有欠发
+                TriggerScore score = new TriggerScore(new Date(), 0);
+                lcingCheck(score);
+            }
+        }
+
+
+    }
+
+    //
+    private void lcingCheck(TriggerScore score) {
+
+        scoreList.add(score);
+        Date now = new Date();
+        Calendar calendar = Calendar.getInstance();
+        calendar.setTime(now);
+        calendar.add(Calendar.HOUR_OF_DAY, -1);
+        //过滤掉超出一个小时的数据
+        List<TriggerScore> collect = scoreList.stream().filter(s -> s.getTriggerTime().getTime() > calendar.getTime().getTime()).collect(Collectors.toList());
+        this.scoreList = collect;
+        if (lastCalcTime == null) {
+            lastCalcTime = new Date();
+        }
+        //如果当前时间减去上一次计算时间已经超过计算周期 如600秒,则再次进行计算
+        if (new Date().getTime() - lastCalcTime.getTime() >= calcCycle * 1000) {
+            Optional<TriggerScore> maxTime = scoreList.stream().max(Comparator.comparing(TriggerScore::getTriggerTime));
+            Optional<TriggerScore> minTime = scoreList.stream().min(Comparator.comparing(TriggerScore::getTriggerTime));
+
+            if (maxTime.isPresent() && minTime.isPresent()) {
+                Long subTime = maxTime.get().getTriggerTime().getTime() - minTime.get().getTriggerTime().getTime();
+                if (subTime > calcCycle * 1000) {
+                    OptionalDouble average = this.scoreList.stream().mapToDouble(TriggerScore::getScore).average();
+                    if (average.isPresent()) {
+                        double asDouble = average.getAsDouble();
+                        calcLcing(asDouble);
+                    }
+                }
+            }
+            lastCalcTime = now;
+
+        }
+
+
+    }
+
+    private void calcLcing(double score) {
+        List<AlarmSnap> saveSnap = new ArrayList<>();
+        Date nowTime = new Date();
+        if (score >= 0.5 && score < 1) {
+            //覆冰初期
+            if (alarmsnap_lcing_lower.getIsOpened() != 0) {
+                alarmsnap_lcing_lower.setIsOpened(1);
+                alarmsnap_lcing_lower.setLastUpdateTime(nowTime);
+                saveSnap.add(alarmsnap_lcing_lower);
+            }
+            if (alarmsnap_lcing_high.getIsOpened() == 1) {
+                alarmsnap_lcing_high.setIsOpened(0);
+                alarmsnap_lcing_high.setLastUpdateTime(nowTime);
+                saveSnap.add(alarmsnap_lcing_high);
+            }
+            if (alarmsnap_lcing_mid.getIsOpened() == 1) {
+                alarmsnap_lcing_mid.setIsOpened(0);
+                alarmsnap_lcing_mid.setLastUpdateTime(nowTime);
+                saveSnap.add(alarmsnap_lcing_mid);
+            }
+        } else if (score >= 1 && score < 2) {
+            //覆冰中期
+            if (alarmsnap_lcing_mid.getIsOpened() != 1) {
+                alarmsnap_lcing_mid.setIsOpened(1);
+                alarmsnap_lcing_mid.setLastUpdateTime(nowTime);
+                saveSnap.add(alarmsnap_lcing_mid);
+            }
+            if (alarmsnap_lcing_lower.getIsOpened() == 1) {
+                alarmsnap_lcing_lower.setIsOpened(0);
+                alarmsnap_lcing_lower.setLastUpdateTime(nowTime);
+                saveSnap.add(alarmsnap_lcing_lower);
+            }
+            if (alarmsnap_lcing_high.getIsOpened() == 1) {
+                alarmsnap_lcing_high.setIsOpened(0);
+                alarmsnap_lcing_high.setLastUpdateTime(nowTime);
+                saveSnap.add(alarmsnap_lcing_high);
+            }
+        } else if (score >= 2) {
+            //覆冰后期
+            if (alarmsnap_lcing_high.getIsOpened() != 1) {
+                alarmsnap_lcing_high.setIsOpened(1);
+                alarmsnap_lcing_high.setLastUpdateTime(nowTime);
+                saveSnap.add(alarmsnap_lcing_high);
+            }
+            if (alarmsnap_lcing_mid.getIsOpened() == 1) {
+                alarmsnap_lcing_mid.setIsOpened(0);
+                alarmsnap_lcing_mid.setLastUpdateTime(nowTime);
+                saveSnap.add(alarmsnap_lcing_mid);
+            }
+            if (alarmsnap_lcing_lower.getIsOpened() == 1) {
+                alarmsnap_lcing_lower.setIsOpened(0);
+                alarmsnap_lcing_lower.setLastUpdateTime(nowTime);
+                saveSnap.add(alarmsnap_lcing_lower);
+            }
+
+        } else {
+            if (alarmsnap_lcing_high.getIsOpened() == 1) {
+                alarmsnap_lcing_high.setIsOpened(0);
+                alarmsnap_lcing_high.setLastUpdateTime(nowTime);
+                saveSnap.add(alarmsnap_lcing_high);
+            }
+            if (alarmsnap_lcing_mid.getIsOpened() == 1) {
+                alarmsnap_lcing_mid.setIsOpened(0);
+                alarmsnap_lcing_mid.setLastUpdateTime(nowTime);
+                saveSnap.add(alarmsnap_lcing_mid);
+            }
+            if (alarmsnap_lcing_lower.getIsOpened() == 1) {
+                alarmsnap_lcing_lower.setIsOpened(0);
+                alarmsnap_lcing_lower.setLastUpdateTime(nowTime);
+                saveSnap.add(alarmsnap_lcing_lower);
+            }
+        }
+        remoteServiceBuilder.alarmSnapService().saveAlarmSnaps(saveSnap);
+
+    }
+
+    @Data
+    class TriggerScore {
+
+        private Date triggerTime;
+        //0,1,2,3 分别代表 无覆冰可能,1为覆冰初期,2为覆冰中期,3为覆冰后期
+        private int score;
+
+        public TriggerScore(Date time, int score) {
+            this.triggerTime = time;
+            this.score = score;
+        }
+    }
+}

+ 96 - 0
sample-kudu/src/main/java/com/gyee/wisdom/samplekudu/lcingcalc/TagInfo.java

@@ -0,0 +1,96 @@
+package com.gyee.wisdom.samplekudu.lcingcalc;
+
+import com.gyee.wisdom.samplekudu.timeseries.*;
+import lombok.Data;
+
+import java.util.Date;
+import java.util.HashMap;
+
+@Data
+public class TagInfo {
+
+    private TsPoint tsPoint;
+
+    private DoubleTsData doubleTsData;
+
+    private BooleanTsData booleanTsData;
+
+    private LongTsData longTsData;
+
+    //本地时间
+    private long localTs;
+
+    public TagInfo(TsPoint value) {
+        tsPoint = value;
+    }
+
+    public void UpdateTsData(HashMap<String, Object> hmp) {
+        long ts = Long.parseLong(hmp.get("ts").toString());
+        if (ts == 0) return;
+        if (ts <= getLastUpdateTime())
+            return;
+
+        short status = ((Integer) hmp.get("status")).shortValue();
+        //每次数据更新的时候,将本地当前时间赋值给localTs
+        long nowTs = new Date().getTime();
+        if (tsPoint.getTsDataType() == TsDataType.BOOLEAN) {
+            if (booleanTsData == null) {
+                Object objValue = hmp.get("booleanValue");
+                String valueStr = objValue.toString();
+                boolean value = "true".equals(valueStr) ? true : false;
+                booleanTsData = new BooleanTsData(ts, status, value);
+                localTs = nowTs;
+            } else {
+                Object objValue = hmp.get("booleanValue");
+                String valueStr = objValue.toString();
+                boolean value = "true".equals(valueStr) ? true : false;
+
+                if (booleanTsData.getBooleanValue() == value)
+                    return;
+                booleanTsData = new BooleanTsData(ts, status, value);
+                localTs = nowTs;
+            }
+
+        } else if (tsPoint.getTsDataType() == TsDataType.DOUBLE) {
+            if (doubleTsData == null){
+                doubleTsData = new DoubleTsData(ts, status, (double) hmp.get("doubleValue"));
+                localTs = nowTs;
+            }
+            else {
+                double value = (double) hmp.get("doubleValue");
+                if (doubleTsData.getDoubleValue() == value)
+                    return;
+                doubleTsData = new DoubleTsData(ts, status, value);
+                localTs = nowTs;
+            }
+        } else if (tsPoint.getTsDataType() == TsDataType.LONG) {
+            if (longTsData == null){
+                longTsData = new LongTsData(ts, status, Long.parseLong(hmp.get("longValue").toString()));
+                localTs = nowTs;
+            }
+
+            else {
+                long value = Long.parseLong(hmp.get("longValue").toString());
+                if (longTsData.getLongValue() == value)
+                    return;
+                longTsData = new LongTsData(ts, status, value);
+                localTs = nowTs;
+            }
+        }
+    }
+
+    public long getLastUpdateTime() {
+        if (tsPoint.getTsDataType() == TsDataType.BOOLEAN) {
+            return booleanTsData == null ? 0 : booleanTsData.getTs();
+        } else if (tsPoint.getTsDataType() == TsDataType.DOUBLE) {
+            return doubleTsData == null ? 0 : doubleTsData.getTs();
+        } else if (tsPoint.getTsDataType() == TsDataType.LONG) {
+            return longTsData == null ? 0 : longTsData.getTs();
+        }
+        return 0;
+    }
+
+    public long getLocalLastUpdateTime(){
+        return this.localTs;
+    }
+}

+ 14 - 0
sample-kudu/src/main/java/com/gyee/wisdom/samplekudu/mapper/TsPointMapper.java

@@ -0,0 +1,14 @@
+package com.gyee.wisdom.samplekudu.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.gyee.wisdom.samplekudu.entity.TsPointEntity;
+import org.apache.ibatis.annotations.Mapper;
+
+/**
+ * @description:
+ * @auther: Wanghs
+ * @date: 2022-11-22
+ */
+@Mapper
+public interface TsPointMapper extends BaseMapper<TsPointEntity> {
+}

+ 11 - 0
sample-kudu/src/main/java/com/gyee/wisdom/samplekudu/mapper/WindturbineMapper.java

@@ -0,0 +1,11 @@
+package com.gyee.wisdom.samplekudu.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.gyee.wisdom.samplekudu.entity.WindturbineEntity;
+import org.apache.ibatis.annotations.Mapper;
+
+
+@Mapper
+public interface WindturbineMapper extends BaseMapper<WindturbineEntity> {
+
+}

+ 28 - 0
sample-kudu/src/main/java/com/gyee/wisdom/samplekudu/service/TsPointService.java

@@ -0,0 +1,28 @@
+package com.gyee.wisdom.samplekudu.service;
+
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.gyee.wisdom.samplekudu.domain.data.LcingTagNameData;
+import com.gyee.wisdom.samplekudu.entity.TsPointEntity;
+import com.gyee.wisdom.samplekudu.mapper.TsPointMapper;
+import org.springframework.stereotype.Service;
+
+import java.util.List;
+
+/**
+ * @description:
+ * @auther: Wanghs
+ * @date: 2022-11-22
+ */
+@Service
+public class TsPointService extends ServiceImpl<TsPointMapper, TsPointEntity> {
+
+  public   List<TsPointEntity> getPointList(String windturbineId, List<String> unifomCodeList) {
+        QueryWrapper<TsPointEntity> wrapper = new QueryWrapper<>();
+        wrapper.eq("THING_ID", windturbineId);
+        wrapper.in("UNIFORM_CODE", unifomCodeList);
+        List<TsPointEntity> entityList = baseMapper.selectList(wrapper);
+        return entityList;
+    }
+
+}

+ 28 - 0
sample-kudu/src/main/java/com/gyee/wisdom/samplekudu/service/WindturbineService.java

@@ -0,0 +1,28 @@
+package com.gyee.wisdom.samplekudu.service;
+
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.gyee.wisdom.samplekudu.entity.TsPointEntity;
+import com.gyee.wisdom.samplekudu.entity.WindturbineEntity;
+import com.gyee.wisdom.samplekudu.mapper.TsPointMapper;
+import com.gyee.wisdom.samplekudu.mapper.WindturbineMapper;
+import org.springframework.stereotype.Service;
+
+import java.util.List;
+
+/**
+ * @description:
+ * @auther: Wanghs
+ * @date: 2022-12-09
+ */
+@Service
+public class WindturbineService extends ServiceImpl<WindturbineMapper, WindturbineEntity> {
+
+    public List<WindturbineEntity>  getWindturbine(String stationId){
+        QueryWrapper<WindturbineEntity> wrapper=new QueryWrapper<WindturbineEntity>();
+        wrapper.eq("windpowerstationid",stationId);
+
+        List<WindturbineEntity> lst = this.baseMapper.selectList(wrapper);
+        return lst;
+    }
+}

+ 86 - 0
sample-kudu/src/main/java/com/gyee/wisdom/samplekudu/taos/TaosConfig.java

@@ -0,0 +1,86 @@
+package com.gyee.wisdom.samplekudu.taos;
+
+import com.alibaba.druid.pool.DruidDataSource;
+import com.taosdata.jdbc.TSDBDriver;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.context.annotation.Configuration;
+
+import javax.sql.DataSource;
+import java.sql.Connection;
+import java.sql.DriverManager;
+import java.util.Properties;
+
+/**
+ * @description:
+ * @auther: Wanghs
+ * @date: 2022-11-23
+ */
+@Configuration
+public class TaosConfig {
+    @Value("${taos.server_ip:192.168.1.60}")
+    private String serverIp;
+
+    @Value("${taos.server_port:6030}")
+    private int serverPort;
+
+    @Value("${taos.db_name:power_test}")
+    private String dbName;
+
+    @Value("${taos.user_name:root}")
+    private String userName;
+
+    @Value("${taos.password:taosdata}")
+    private String password;
+
+    @Value("${taos.pool_size:10}")
+    private int poolSize;
+
+    @Value("${taos.max_pool_size:100}")
+    private int maxPoolSize;
+
+    @Value("${taos.driver_type:com.taosdata.jdbc.rs.RestfulDriver}")
+    private String driverType;
+
+    @Value("${taos.distinguish_case:false}")
+    private Boolean distinguishCase;
+
+    private Connection connection = null;
+
+    public Connection getInstance() {
+        if (null == connection)
+            connection = getConnection();
+
+        return connection;
+    }
+
+
+    private Connection getConnection() {
+        Connection connection = null;
+
+        try {
+
+            Class.forName(driverType);
+            String jdbcUrl = "jdbc:TAOS-RS://" + serverIp + ":" + serverPort + "/" + dbName + "?user=" + userName + "&password=" + password;
+            if (driverType.equals("com.taosdata.jdbc.TSDBDriver"))
+                jdbcUrl = "jdbc:TAOS://" + serverIp + ":" + serverPort + "/" + dbName + "?user=" + userName + "&password=" + password;
+            Properties connProps = new Properties();
+            connProps.setProperty(TSDBDriver.PROPERTY_KEY_CHARSET, "UTF-8");
+            connProps.setProperty(TSDBDriver.PROPERTY_KEY_LOCALE, "en_US.UTF-8");
+            connProps.setProperty(TSDBDriver.PROPERTY_KEY_TIME_ZONE, "UTC-8");
+            connection = DriverManager.getConnection(jdbcUrl, connProps);
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+
+
+        return connection;
+    }
+
+    public String getTableName(String tagName) {
+
+        if (distinguishCase)
+            return dbName + ".`" + tagName + "`";
+        else
+            return dbName + "." + tagName;
+    }
+}

+ 75 - 0
sample-kudu/src/main/java/com/gyee/wisdom/samplekudu/taos/TaosHistoryDao.java

@@ -0,0 +1,75 @@
+package com.gyee.wisdom.samplekudu.taos;
+
+import com.gyee.wisdom.samplekudu.exception.TaosRunException;
+import com.gyee.wisdom.samplekudu.timeseries.*;
+import com.gyee.wisdom.samplekudu.util.ResultCode;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.lang3.time.DateFormatUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+import java.sql.ResultSet;
+import java.sql.Statement;
+import java.util.*;
+
+@Slf4j
+@Component
+public class TaosHistoryDao {
+
+    private long year_time = 8640000000L;
+
+    @Autowired
+    TaosConfig taosConfig;
+    @Autowired
+    ThreadPoolTaskConfig taskConfig;
+
+    public List<TsData> getTsDataHistory(String tagName, String dataType, Long startTime, Long endTime, int interVal) throws Exception {
+        if (dataType.equals("double")||dataType.toUpperCase().contains("FLOAT")) {
+            return getDoubleTsDataHistory(tagName, startTime, endTime, interVal);
+        } else {
+            return getBooleanTsDataHistory(tagName, startTime, endTime, interVal);
+        }
+    }
+
+    public List<TsData> getDoubleTsDataHistory(String tagName, Long startTime, Long endTime, int interVal) throws Exception {
+        List<TsData> tsDataList = new ArrayList<>();
+
+        Statement st = taosConfig.getInstance().createStatement();
+        String sql = getHistorySqlStr(tagName, startTime, endTime, interVal);
+        ResultSet rs = st.executeQuery(sql);
+        while (rs.next()) {
+            tsDataList.add(new DoubleTsData(rs.getTimestamp(1).getTime(), (short) 0, rs.getDouble(2)));
+        }
+
+        return tsDataList;
+    }
+
+
+    public List<TsData> getBooleanTsDataHistory(String tagName, Long startTime, Long endTime, int interVal) throws Exception {
+        List<TsData> tsDataList = new ArrayList<>();
+
+        Statement st = taosConfig.getInstance().createStatement();
+        String sql = getHistorySqlStr(tagName, startTime, endTime, interVal);
+        ResultSet rs = st.executeQuery(sql);
+        while (rs.next()) {
+            tsDataList.add(new BooleanTsData(rs.getTimestamp(1).getTime(), (short) 0, rs.getInt(2)==1?true:false));
+        }
+        return tsDataList;
+    }
+
+
+    private String getHistorySqlStr(String tagName, Long startTime, Long endTime, int interVal) throws TaosRunException {
+        StringBuilder sb = new StringBuilder();
+
+
+        sb.append("select last(value) from ");
+        sb.append(taosConfig.getTableName(tagName));
+        sb.append(" where ts>='").append(DateFormatUtils.format(startTime, "yyyy-MM-dd HH:mm:ss:SSS"));
+        sb.append("' and ts<'").append(DateFormatUtils.format(endTime, "yyyy-MM-dd HH:mm:ss:SSS"));
+        sb.append("' interval(").append(interVal).append("s) fill(prev)");
+
+        return sb.toString();
+    }
+
+
+}

+ 76 - 0
sample-kudu/src/main/java/com/gyee/wisdom/samplekudu/taos/TaskCallable.java

@@ -0,0 +1,76 @@
+package com.gyee.wisdom.samplekudu.taos;
+
+import com.gyee.wisdom.samplekudu.timeseries.BooleanTsData;
+import com.gyee.wisdom.samplekudu.timeseries.DoubleTsData;
+import com.gyee.wisdom.samplekudu.timeseries.TsData;
+import com.gyee.wisdom.samplekudu.timeseries.TsDataType;
+import com.gyee.wisdom.samplekudu.util.StringUtil;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.lang3.time.DateFormatUtils;
+
+import java.sql.Connection;
+import java.sql.ResultSet;
+import java.sql.Statement;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.concurrent.Callable;
+
+@Slf4j
+public class TaskCallable implements Callable<Map<String, TsData>> {
+
+    private Connection connection;
+    private long time;
+    private String tagName;
+    private TsDataType type;
+
+    private long day_time = 86400000L;
+    private long year_time = 8640000000L;
+
+    public TaskCallable(Connection connection, long time, String tagName, TsDataType type) {
+        this.connection = connection;
+        this.time = time;
+        this.tagName = tagName;
+        this.type = type;
+    }
+
+
+    @Override
+    public Map<String, TsData> call() {
+        TsData tsData = null;
+        Statement st = null;
+        ResultSet rs = null;
+        Map<String, TsData> result = new HashMap<>();
+
+        if (StringUtil.isBlank(tagName))
+            return result;
+
+        try {
+            st = this.connection.createStatement();
+//            String point = TaosCovertUtil.coverStationPrefix(this.tagName) + "." + this.tagName.replace(".", "_");
+//            String tableName = dbName+ "." + this.tagName;
+            String sql = "select last_row(*) from " + "tst" + " where point_time>='"
+                    + DateFormatUtils.format(this.time - year_time, "yyyy-MM-dd HH:mm:ss:SSS") + "'"
+                    + " and point_time <='" + DateFormatUtils.format(this.time, "yyyy-MM-dd HH:mm:ss:SSS") + "'";
+            log.info(sql);
+            rs = st.executeQuery(sql);
+            if (rs.next()) {
+                if (this.type == TsDataType.DOUBLE)
+                    tsData = new DoubleTsData(this.time, (short) 0, rs.getDouble(2));
+                else if (this.type == TsDataType.BOOLEAN)
+                    tsData = new BooleanTsData(this.time, (short) 0, rs.getBoolean(2));
+            }
+            result.put(this.tagName, tsData);
+        } catch (Exception e) {
+        } finally {
+//            try {
+//                if(rs != null)
+//                    rs.close();
+//                if(st != null)
+//                    st.close();
+//            } catch (SQLException e) {
+//                e.printStackTrace();
+//            }
+        }
+        return result;
+    }
+}

+ 57 - 0
sample-kudu/src/main/java/com/gyee/wisdom/samplekudu/taos/ThreadPoolTaskConfig.java

@@ -0,0 +1,57 @@
+package com.gyee.wisdom.samplekudu.taos;
+
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
+
+import java.util.concurrent.ThreadPoolExecutor;
+
+@Configuration
+public class ThreadPoolTaskConfig {
+    /**
+     *   默认情况下,在创建了线程池后,线程池中的线程数为0,当有任务来之后,就会创建一个线程去执行任务,
+     *	当线程池中的线程数目达到corePoolSize后,就会把到达的任务放到缓存队列当中;
+     *  当队列满了,就继续创建线程,当线程数量大于等于maxPoolSize后,开始使用拒绝策略拒绝
+     */
+
+    /** 核心线程数(默认线程数) */
+    private static final int corePoolSize = 20;
+    /** 最大线程数 */
+    private static final int maxPoolSize = 50;
+    /** 允许线程空闲时间(单位:默认为秒) */
+    private static final int keepAliveTime = 60;
+    /** 缓冲队列大小 */
+    private static final int queueCapacity = 100;
+    /** 允许等待最长时间 */
+    private static final int awaitTime = 15;
+    /** 线程池名前缀 */
+    private static final String threadNamePrefix = "GYEE-Thread-";
+
+    private ThreadPoolTaskExecutor executor;
+
+    public ThreadPoolTaskExecutor getInstance(){
+        if (executor == null)
+            executor = taskExecutor();
+
+        return executor;
+    }
+
+    @Bean
+    public ThreadPoolTaskExecutor taskExecutor(){
+        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
+        executor.setCorePoolSize(corePoolSize);
+        executor.setMaxPoolSize(maxPoolSize);
+        executor.setQueueCapacity(queueCapacity);
+        executor.setKeepAliveSeconds(keepAliveTime);
+        executor.setThreadNamePrefix(threadNamePrefix);
+        executor.setAwaitTerminationSeconds(awaitTime);
+
+        // 线程池对拒绝任务的处理策略
+        // CallerRunsPolicy:由调用线程(提交任务的线程)处理该任务
+        executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
+        // 初始化
+        executor.initialize();
+        return executor;
+    }
+
+}

+ 46 - 0
sample-kudu/src/main/java/com/gyee/wisdom/samplekudu/timeseries/BaseTsQuery.java

@@ -0,0 +1,46 @@
+package com.gyee.wisdom.samplekudu.timeseries;
+
+import lombok.Data;
+
+import java.util.Date;
+
+@Data
+public class BaseTsQuery implements TsQuery {
+
+    private final TsPoint tsPoint;
+    private final long startTs;
+    private final long endTs;
+    private final int interval;
+    private final int limit ;
+    private final Interpolation interpolation;
+
+
+    public BaseTsQuery(TsPoint tsPoint, long startTs, long endTs, int interval, int limit, Interpolation interpolation) {
+        this.tsPoint = tsPoint;
+        this.startTs = startTs;
+        this.endTs = endTs;
+        this.interval = interval;
+        this.limit = limit;
+        this.interpolation = interpolation;
+    }
+
+    public BaseTsQuery(TsPoint tsPoint, long startTs, long endTs) {
+        this(tsPoint, startTs, endTs, 1, 1, Interpolation.RAW);
+    }
+    @Override
+    public Date[] getDateArray() {
+        if (interpolation == Interpolation.SNAP && startTs > 0 && endTs >0 && interval > 0 && endTs > startTs ) {
+            int count = Math.round ((endTs - startTs)/interval/1000);
+            int length = count;// <= limit ? count : limit;
+            Date[] result = new Date[length];
+            for (int i=0;i<length;i++) {
+                long ts = startTs + (long)i*interval*1000;
+                result[i] = new Date(ts);
+            }
+
+            return result;
+        }
+        return  null;
+    }
+
+}

+ 38 - 0
sample-kudu/src/main/java/com/gyee/wisdom/samplekudu/timeseries/BasicTsData.java

@@ -0,0 +1,38 @@
+package com.gyee.wisdom.samplekudu.timeseries;
+
+/**
+ * @author songwb<songwb@aliyun.com>
+ */
+public abstract class BasicTsData implements TsData, Comparable<BasicTsData>{
+
+    private final long ts;
+
+    private final short status;
+
+    public BasicTsData(long ts, short status) {
+        this.ts = ts;
+        this.status = status;
+    }
+    @Override
+    public long getTs() {
+        return ts;
+    }
+    @Override
+    public short getStatus() {
+        return status;
+    }
+
+    @Override
+    public int compareTo(BasicTsData o) {
+        return Long.compare(ts, o.ts);
+    }
+
+    @Override
+    public String toString() {
+        return "BasicTsData{ts='" + ts +
+                "', status='" + this.getStatus() +
+                "'}";
+    }
+
+}
+

+ 62 - 0
sample-kudu/src/main/java/com/gyee/wisdom/samplekudu/timeseries/BasicTsPoint.java

@@ -0,0 +1,62 @@
+package com.gyee.wisdom.samplekudu.timeseries;
+
+import lombok.Data;
+
+/**
+ * @author songwb<songwb@aliyun.com>
+ */
+@Data
+public class BasicTsPoint implements TsPoint {
+
+    private final String id;
+
+    private TsDataType tsDataType;
+
+    private  String thingId;
+
+    private  String thingType;
+
+    private  String uniformCode;
+
+    private String tag;
+
+    public BasicTsPoint(String id,  TsDataType tsDataType) {
+        this.id = id;
+        this.tsDataType = tsDataType;
+    }
+    @Override
+    public String getId() { return id; }
+    @Override
+    public TsDataType getTsDataType() {return tsDataType; }
+
+    @Override
+    public String getUniformCode(){
+       return uniformCode;
+    }
+
+
+    @Override
+    public String getThingId(){
+        return thingId;
+    }
+
+    @Override
+    public String getThingType(){
+        return thingType;
+    }
+
+    @Override
+    public String toString() {
+        return "BasicTsPoint{id='" + id +
+                "', dataType='" + this.getTsDataType() +
+                "'}";
+    }
+
+
+    @Override
+    public String getTag(){
+        return tag;
+    }
+
+}
+

+ 24 - 0
sample-kudu/src/main/java/com/gyee/wisdom/samplekudu/timeseries/BlobTsData.java

@@ -0,0 +1,24 @@
+package com.gyee.wisdom.samplekudu.timeseries;
+
+import java.util.Base64;
+
+/**
+ * @author songwb<songwb@aliyun.com>
+ */
+public class BlobTsData extends BasicTsData {
+
+    private final byte[] blob;
+
+    public BlobTsData(long ts, short status, byte[] blob) {
+        super(ts, status);
+        this.blob = blob;
+    }
+
+    //public byte[] getBlob() { return  blob ;}
+
+    public String getBlobValue() {
+        return Base64.getEncoder().encodeToString(blob);
+    }
+
+}
+

+ 22 - 0
sample-kudu/src/main/java/com/gyee/wisdom/samplekudu/timeseries/BlobWriteTsData.java

@@ -0,0 +1,22 @@
+package com.gyee.wisdom.samplekudu.timeseries;
+
+import lombok.Data;
+
+import java.util.Base64;
+
+/**
+ * @descrition:
+ * @author:Wanghs
+ * @date:2018-05-04
+ */
+@Data
+public class BlobWriteTsData {
+    private String tagName;
+    private long ts;
+    private  byte[]blob;
+
+    public String getValue() {
+        return Base64.getEncoder().encodeToString(blob);
+    }
+
+}

+ 19 - 0
sample-kudu/src/main/java/com/gyee/wisdom/samplekudu/timeseries/BooleanTsData.java

@@ -0,0 +1,19 @@
+package com.gyee.wisdom.samplekudu.timeseries;
+
+/**
+ * @author songwb<songwb@aliyun.com>
+ */
+public class BooleanTsData extends BasicTsData {
+
+    private final boolean actualValue;
+
+    public BooleanTsData(long ts, short status, boolean actualValue) {
+        super(ts, status);
+        this.actualValue = actualValue;
+    }
+    public boolean getBooleanValue() {
+        return actualValue;
+    }
+
+}
+

+ 19 - 0
sample-kudu/src/main/java/com/gyee/wisdom/samplekudu/timeseries/BooleanWriteTsData.java

@@ -0,0 +1,19 @@
+package com.gyee.wisdom.samplekudu.timeseries;
+
+import lombok.Data;
+
+/**
+ * @descrition:
+ * @author:Wanghs
+ * @date:2018-05-04
+ */
+@Data
+public class BooleanWriteTsData  {
+    private String tagName;
+    private long ts;
+    private boolean actualValue;
+
+    public boolean getValue() {
+        return this.actualValue;
+    }
+}

+ 18 - 0
sample-kudu/src/main/java/com/gyee/wisdom/samplekudu/timeseries/Coordinate.java

@@ -0,0 +1,18 @@
+package com.gyee.wisdom.samplekudu.timeseries;
+
+import lombok.AllArgsConstructor;
+import lombok.Data;
+
+/**
+ * @author songwb<songwb@aliyun.com>
+ */
+@Data
+@AllArgsConstructor
+public class Coordinate {
+
+    private double latitude;
+
+    private double longitude;
+
+}
+

+ 26 - 0
sample-kudu/src/main/java/com/gyee/wisdom/samplekudu/timeseries/CoordinateTsData.java

@@ -0,0 +1,26 @@
+package com.gyee.wisdom.samplekudu.timeseries;
+
+/**
+ * @author songwb<songwb@aliyun.com>
+ */
+public class CoordinateTsData extends BasicTsData {
+
+    private final Coordinate coordinate;
+
+    public CoordinateTsData(long ts, short status, double latitude, double longitude) {
+        super(ts, status);
+        this.coordinate = new Coordinate(latitude, longitude);
+    }
+
+    public CoordinateTsData(long ts, short status, Coordinate coordinate) {
+        super(ts, status);
+        this.coordinate = coordinate;
+    }
+
+    public Coordinate getCoordinateValue() {
+        return coordinate;
+        //return String.format("{\"longitude\":%f,\"latitude\":\"%f\"}", longitude, latitude);
+    }
+
+}
+

+ 21 - 0
sample-kudu/src/main/java/com/gyee/wisdom/samplekudu/timeseries/CoordinateWriteTsData.java

@@ -0,0 +1,21 @@
+package com.gyee.wisdom.samplekudu.timeseries;
+
+import lombok.Data;
+
+/**
+ * @descrition:
+ * @author:Wanghs
+ * @date:2018-05-04
+ */
+@Data
+public class CoordinateWriteTsData  {
+
+    private String tagName;
+    private long ts;
+    private  double latitude;
+    private  double longitude;
+
+    public double getLatitude() { return  latitude ;}
+    public double getLongitude() {return  longitude; }
+
+}

+ 30 - 0
sample-kudu/src/main/java/com/gyee/wisdom/samplekudu/timeseries/DoubleStatData.java

@@ -0,0 +1,30 @@
+package com.gyee.wisdom.samplekudu.timeseries;
+
+/**
+ * @author songwb<songwb@aliyun.com>
+ */
+public class DoubleStatData {
+
+    private DoubleTsData avg;
+    private DoubleTsData max;
+    private DoubleTsData min;
+
+    public DoubleStatData(DoubleTsData avg, DoubleTsData max, DoubleTsData min) {
+        this.avg = avg;
+        this.max = max;
+        this.min = min;
+    }
+
+    public DoubleTsData getAvg() {
+        return avg;
+    }
+
+    public DoubleTsData getMax() {
+        return max;
+    }
+
+    public DoubleTsData getMin() {
+        return min;
+    }
+}
+

+ 33 - 0
sample-kudu/src/main/java/com/gyee/wisdom/samplekudu/timeseries/DoubleTsData.java

@@ -0,0 +1,33 @@
+package com.gyee.wisdom.samplekudu.timeseries;
+
+/**
+ * @author songwb<songwb@aliyun.com>
+ */
+public class DoubleTsData extends BasicTsData {
+
+    private final double actualValue;
+
+    public DoubleTsData(long ts, short status, double actualValue) {
+        super(ts, status);
+        this.actualValue = actualValue;
+    }
+
+
+    public double getDoubleValue() {
+        return actualValue;
+    }
+
+//    public String getValue() {
+//        return Double.toString(actualValue);
+//    }
+
+    @Override
+    public String toString() {
+        return "DoubleTsData{ts='" + this.getTs() +
+                "', status='" + this.getStatus() +
+                "', value='" + this.getDoubleValue() +
+                "'}";
+    }
+
+}
+

+ 19 - 0
sample-kudu/src/main/java/com/gyee/wisdom/samplekudu/timeseries/DoubleWriteTsData.java

@@ -0,0 +1,19 @@
+package com.gyee.wisdom.samplekudu.timeseries;
+
+import lombok.Data;
+
+/**
+ * @descrition:
+ * @author:Wanghs
+ * @date:2018-05-04
+ */
+@Data
+public class DoubleWriteTsData  {
+    private String tagName;
+    private long ts;
+    private double actualValue;
+
+    public double getValue() {
+        return this.actualValue;
+    }
+}

+ 28 - 0
sample-kudu/src/main/java/com/gyee/wisdom/samplekudu/timeseries/GeneralTsData.java

@@ -0,0 +1,28 @@
+package com.gyee.wisdom.samplekudu.timeseries;
+
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import java.util.Optional;
+
+/**
+ * @author songwb<songwb@aliyun.com>
+ */
+@Data
+@AllArgsConstructor
+@NoArgsConstructor
+public class GeneralTsData implements TsData {
+
+    private long ts;
+    private short status;
+    private Optional<Double> doubleValue;
+    private Optional<Long> longValue;
+    private Optional<Boolean> booleanValue;
+    private Optional<String> stringValue;
+    private Optional<String> blobValue;
+    private Optional<Coordinate> coordinateValue;
+
+
+}
+

+ 18 - 0
sample-kudu/src/main/java/com/gyee/wisdom/samplekudu/timeseries/IntegerTsData.java

@@ -0,0 +1,18 @@
+package com.gyee.wisdom.samplekudu.timeseries;
+
+/**
+ * @Auther: ruyuan
+ * @Date: 2019-05-04 17:26
+ * @Description:
+ */
+public class IntegerTsData extends BasicTsData {
+
+    private final Integer actualValue;
+    public IntegerTsData(long ts, short status, Integer actualValue) {
+        super(ts, status);
+        this.actualValue = actualValue;
+    }
+    public Integer getIntegerValue() {
+        return actualValue;
+    }
+}

+ 8 - 0
sample-kudu/src/main/java/com/gyee/wisdom/samplekudu/timeseries/Interpolation.java

@@ -0,0 +1,8 @@
+
+package com.gyee.wisdom.samplekudu.timeseries;
+
+public enum Interpolation {
+    SNAP,   // 历史快照数据
+    INTERPOLATION, //插值
+    RAW    //原始数据
+}

+ 24 - 0
sample-kudu/src/main/java/com/gyee/wisdom/samplekudu/timeseries/LongTsData.java

@@ -0,0 +1,24 @@
+package com.gyee.wisdom.samplekudu.timeseries;
+
+/**
+ * @author songwb<songwb@aliyun.com>
+ */
+public class LongTsData extends BasicTsData {
+
+    private final long actualValue;
+
+    public LongTsData(long ts, short status, long actualValue) {
+        super(ts, status);
+        this.actualValue = actualValue;
+    }
+
+    public long getLongValue() {
+        return actualValue;
+    }
+
+//    public String getValue() {
+//        return Long.toString(actualValue);
+//    }
+
+}
+

+ 20 - 0
sample-kudu/src/main/java/com/gyee/wisdom/samplekudu/timeseries/LongWriteTsData.java

@@ -0,0 +1,20 @@
+package com.gyee.wisdom.samplekudu.timeseries;
+
+import lombok.Data;
+
+/**
+ * @descrition:
+ * @author:Wanghs
+ * @date:2018-05-04
+ */
+@Data
+public class LongWriteTsData  {
+
+    private String tagName;
+    private long ts;
+    private long actualValue;
+
+    public long getValue() {
+        return this.actualValue;
+    }
+}

+ 24 - 0
sample-kudu/src/main/java/com/gyee/wisdom/samplekudu/timeseries/StringTsData.java

@@ -0,0 +1,24 @@
+package com.gyee.wisdom.samplekudu.timeseries;
+
+/**
+ * @author songwb<songwb@aliyun.com>
+ */
+public class StringTsData extends BasicTsData {
+
+    private final String actualValue;
+
+    public StringTsData(long ts, short status, String actualValue) {
+        super(ts, status);
+        this.actualValue = actualValue;
+    }
+
+//    public String getActualValue() {
+//        return actualValue;
+//    }
+
+    public String getStringValue() {
+        return actualValue;
+    }
+
+}
+

+ 20 - 0
sample-kudu/src/main/java/com/gyee/wisdom/samplekudu/timeseries/StringWriteTsData.java

@@ -0,0 +1,20 @@
+package com.gyee.wisdom.samplekudu.timeseries;
+
+import lombok.Data;
+
+/**
+ * @descrition:String类型写入实体类
+ * @author:Wanghs
+ * @date:2018-05-04
+ */
+@Data
+public class StringWriteTsData  {
+    private String tagName;
+    private long ts;
+    private String actualValue;
+
+    public String getValue() {
+        return this.actualValue;
+    }
+
+}

+ 15 - 0
sample-kudu/src/main/java/com/gyee/wisdom/samplekudu/timeseries/TsData.java

@@ -0,0 +1,15 @@
+package com.gyee.wisdom.samplekudu.timeseries;
+
+/**
+ * @author songwb<songwb@aliyun.com>
+ */
+public interface TsData {
+
+    long getTs();
+
+    short getStatus();
+
+    //double getValue();
+
+}
+

+ 15 - 0
sample-kudu/src/main/java/com/gyee/wisdom/samplekudu/timeseries/TsDataType.java

@@ -0,0 +1,15 @@
+package com.gyee.wisdom.samplekudu.timeseries;
+
+/**
+ * @author songwb<songwb@aliyun.com>
+ */
+public enum TsDataType {
+    LONG,
+    DOUBLE,
+    BOOLEAN,
+    STRING,
+    BLOB,
+    COORDINATE
+
+}
+

+ 21 - 0
sample-kudu/src/main/java/com/gyee/wisdom/samplekudu/timeseries/TsPoint.java

@@ -0,0 +1,21 @@
+package com.gyee.wisdom.samplekudu.timeseries;
+
+/**
+ * @author songwb<songwb @ aliyun.com>
+ */
+public interface TsPoint {
+
+    String getId();
+
+    String getThingId();
+
+    String getThingType();
+
+    String getUniformCode();
+
+    TsDataType getTsDataType();
+
+    //reids库
+    String getTag();
+}
+

+ 60 - 0
sample-kudu/src/main/java/com/gyee/wisdom/samplekudu/timeseries/TsPointData.java

@@ -0,0 +1,60 @@
+package com.gyee.wisdom.samplekudu.timeseries;
+
+
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+/**
+ * @author songwb<songwb@aliyun.com>
+ */
+@Data
+@AllArgsConstructor
+@NoArgsConstructor
+public class TsPointData {
+
+    private String tagName;
+    private GeneralTsData tsData;
+
+    public TsDataType findDataType() {
+        if (tsData.getDoubleValue().isPresent()){
+            return TsDataType.DOUBLE;
+        }
+        else if (tsData.getBooleanValue().isPresent()){
+            return TsDataType.BOOLEAN;
+        }
+        else if (tsData.getLongValue().isPresent()){
+            return TsDataType.LONG;
+        }
+
+        else if (tsData.getStringValue().isPresent()){
+            return TsDataType.STRING;
+        }
+
+        else if (tsData.getBlobValue().isPresent()){
+            return TsDataType.BLOB;
+        }
+
+        else if (tsData.getCoordinateValue().isPresent()){
+            return TsDataType.COORDINATE;
+        }
+
+
+        return TsDataType.DOUBLE;
+    }
+    /**
+     * 获取 double 类型值
+     * @return
+     */
+    public double getValue() {
+        if (tsData.getDoubleValue().isPresent()) {
+            return tsData.getDoubleValue().get();
+        } else if (tsData.getBooleanValue().isPresent()) {
+            return tsData.getBooleanValue().get() ? 1.0 : 0.0;
+        } else if (tsData.getLongValue().isPresent()) {
+            return tsData.getLongValue().get();
+        }
+        return 0.0;
+    }
+}
+

+ 23 - 0
sample-kudu/src/main/java/com/gyee/wisdom/samplekudu/timeseries/TsPointDataList.java

@@ -0,0 +1,23 @@
+package com.gyee.wisdom.samplekudu.timeseries;
+
+
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import java.util.List;
+
+/**
+ * @author songwb<songwb@aliyun.com>
+ */
+@Data
+@AllArgsConstructor
+@NoArgsConstructor
+public class TsPointDataList {
+
+    private String tagName;
+
+    private List<GeneralTsData> tsDataList;
+
+}
+

+ 21 - 0
sample-kudu/src/main/java/com/gyee/wisdom/samplekudu/timeseries/TsQuery.java

@@ -0,0 +1,21 @@
+package com.gyee.wisdom.samplekudu.timeseries;
+
+import java.util.Date;
+
+public interface TsQuery {
+
+    TsPoint getTsPoint();
+
+    long getStartTs();
+
+    long getEndTs();
+
+    // 单位秒
+    int getInterval();
+
+    int getLimit();
+
+    Interpolation getInterpolation();
+
+    Date[] getDateArray();
+}

+ 26 - 0
sample-kudu/src/main/java/com/gyee/wisdom/samplekudu/timeseries/websocket/SubscribeMessaage.java

@@ -0,0 +1,26 @@
+package com.gyee.wisdom.samplekudu.timeseries.websocket;
+
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import java.util.Optional;
+
+/**
+ * @author songwb<songwb@aliyun.com>
+ */
+@Data
+@AllArgsConstructor
+@NoArgsConstructor
+public class SubscribeMessaage {
+
+    private Optional<String> tagNames;
+
+    private Optional<String> thingType;
+
+    private Optional<String> thingId;
+
+    private Optional<String> uniformCodes;
+
+}
+

+ 33 - 0
sample-kudu/src/main/java/com/gyee/wisdom/samplekudu/transport/AlarmSnap.java

@@ -0,0 +1,33 @@
+package com.gyee.wisdom.samplekudu.transport;
+
+import com.fasterxml.jackson.annotation.JsonFormat;
+import lombok.Data;
+
+import java.io.Serializable;
+import java.util.Date;
+
+@Data
+public class AlarmSnap implements Serializable{
+
+    private Long id;
+    private String stationId;
+    private String projectId;
+    private String lineId;
+    private String windturbineId;
+    private int alertValue;
+    private String category1;
+    private String category2;
+    private String category3;
+    private String rank;
+    private int isOpened;
+    @JsonFormat(pattern="yyyy-MM-dd HH:mm:ss",timezone="GMT+8")
+    private Date lastUpdateTime;
+    private String stationName;
+    private String projectName;
+    private String lineName;
+    private String windturbineName;
+    private String alertText;
+    private String modelId;
+    private String testingpointKey;
+    private String dataInfo;
+}

+ 54 - 0
sample-kudu/src/main/java/com/gyee/wisdom/samplekudu/transport/AlarmSnapService.java

@@ -0,0 +1,54 @@
+package com.gyee.wisdom.samplekudu.transport;
+
+import feign.Headers;
+import feign.Param;
+import feign.RequestLine;
+
+import java.util.List;
+
+public interface AlarmSnapService {
+
+	@RequestLine("GET /alarm/snap/{snapId}")
+	AlarmSnap queryById(@Param(value = "snapId") long snapId);
+
+	@RequestLine("GET /alarm/snap/single?windturbineid={wtId}&alertvalue={alertValue}")
+	AlarmSnap queryOneByWtId(
+			@Param(value = "wtId") String wtId,
+			@Param(value = "alertValue") Integer alertValue
+	);
+
+	@RequestLine("GET /alarm/snap/single?alertvalue={alertValue}&stationid={stId}")
+	AlarmSnap queryOneByStId(
+			@Param(value = "stId") String stId,
+			@Param(value = "alertValue") Integer alertValue
+	);
+
+	@RequestLine("GET /alarm/snap/single?testingpointkey={tagId}")
+	AlarmSnap queryOneByTagId( @Param(value = "tagId") String tagId );
+
+	@RequestLine("GET /alarm/snap?stationid={stationid}&windturbineid={windturbineid}&category1={category1}&" +
+			"category2={category2}&rank={rank}&modelid={modelid}&isopened={isopened}&" +
+			"keyword={keyword}&starttime={starttime}&endtime={endtime}")
+	public List<AlarmSnap> queryAll(
+            @Param(value = "stationid") String stId,
+            @Param(value = "windturbineid") String wtId,
+            @Param(value = "category1") String category1,
+            @Param(value = "category2") String category2,
+            @Param(value = "rank") String rank,
+            @Param(value = "modelid") String modelId,
+            @Param(value = "isopened") Integer isOpened,
+            @Param(value = "keyword") String keyWord,
+            @Param(value = "starttime") String startTime,
+            @Param(value = "endtime") String endTime
+    );
+
+	@Headers({"Content-Type: application/json","Accept: application/json"})
+	@RequestLine("POST /alarm/snap")
+	void saveAlarmSnap(AlarmSnap alarmSnap);
+
+	@Headers({"Content-Type: application/json","Accept: application/json"})
+	@RequestLine("POST /alarm/snap/batch")
+	void saveAlarmSnaps(List<AlarmSnap> alarmSnaps);
+
+
+}

+ 33 - 0
sample-kudu/src/main/java/com/gyee/wisdom/samplekudu/transport/RemoteServiceBuilder.java

@@ -0,0 +1,33 @@
+package com.gyee.wisdom.samplekudu.transport;
+
+import com.gyee.wisdom.samplekudu.config.ConfigProperties;
+import feign.Feign;
+import feign.Request;
+import feign.Retryer;
+import feign.jackson.JacksonDecoder;
+import feign.jackson.JacksonEncoder;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+
+
+@Configuration
+public class RemoteServiceBuilder {
+
+    @Autowired
+    private ConfigProperties configProperties;
+//    public String shardingSevice = "http://localhost:8075";
+
+    @Bean
+    public AlarmSnapService alarmSnapService() {
+        return Feign.builder()
+                .encoder(new JacksonEncoder())
+                .decoder(new JacksonDecoder())
+                .options(new Request.Options(1000, 3500))
+                .retryer(new Retryer.Default(5000, 5000, 3))
+                .target(AlarmSnapService.class, configProperties.getShardingServiceUrl());
+    }
+
+
+
+}

+ 100 - 0
sample-kudu/src/main/java/com/gyee/wisdom/samplekudu/transport/RestfulClient.java

@@ -0,0 +1,100 @@
+package com.gyee.wisdom.samplekudu.transport;
+
+import com.gyee.wisdom.samplekudu.config.ConfigProperties;
+import com.gyee.wisdom.samplekudu.lcingcalc.CacheService;
+import com.gyee.wisdom.samplekudu.lcingcalc.TagInfo;
+import com.gyee.wisdom.samplekudu.timeseries.TsPointData;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.http.HttpStatus;
+import org.springframework.http.ResponseEntity;
+import org.springframework.http.client.SimpleClientHttpRequestFactory;
+import org.springframework.stereotype.Service;
+import org.springframework.web.client.RestTemplate;
+
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+@Service
+@Slf4j
+public class RestfulClient {
+
+    @Autowired
+    private ConfigProperties configProperties;
+
+    @Autowired
+    private CacheService cacheService;
+
+    private Map<String, TagInfo> tagInfoMap;
+
+    private RestTemplate restTemplate;
+
+    private String adpUrl;
+
+    private String getAdpUrl() {
+        if (adpUrl == null) {
+            adpUrl = configProperties.getServiceUrl();
+        }
+
+        return adpUrl;
+    }
+
+    private String adpLatestUrl;
+
+    private String getAdpLatestUrl() {
+        if (adpLatestUrl == null) {
+            adpLatestUrl = getAdpUrl() + "/latest?keys=";
+        }
+        return adpLatestUrl;
+    }
+
+    private RestTemplate getRestTemplate() {
+        if (restTemplate == null) {
+            //复杂构造函数的使用
+            SimpleClientHttpRequestFactory requestFactory = new SimpleClientHttpRequestFactory();
+            requestFactory.setConnectTimeout(10000);// 设置超时
+            requestFactory.setReadTimeout(10000);
+            restTemplate = new RestTemplate(requestFactory);
+        }
+
+        return restTemplate;
+    }
+
+    private Map<String, TagInfo> getTagInfoMap() {
+        return cacheService.getTagInfoMap();
+    }
+
+    public void getLatest(String keys) throws Exception {
+
+        String url = getAdpLatestUrl() + keys;
+        ResponseEntity<Object> resp = getRestTemplate().getForEntity(url, Object.class);
+        if (resp.getStatusCode() == HttpStatus.OK) {
+            HashMap<String, HashMap<String, Object>> map = (HashMap<String, HashMap<String, Object>>) resp.getBody();
+            if (map != null && map.size() > 0) {
+                for (Map.Entry<String, HashMap<String, Object>> entry : map.entrySet()) {
+                    try {
+                        String tagId = entry.getKey();
+                        TagInfo tagInfo = getTagInfoMap().get(tagId);
+                        tagInfo.UpdateTsData(entry.getValue());
+                    } catch (Exception ex) {
+                        log.error(ex.getMessage());
+                        //System.out.println(ex.getMessage());
+                    }
+                }
+            }
+
+            //已成功取得数据,通知计算线程可以开始运算了
+            if (cacheService.getReadRtdbSuccess() == false)
+                cacheService.setReadRtdbSuccess(true);
+        } else {
+            log.error(resp.getStatusCodeValue() + "");
+        }
+
+
+    }
+
+
+
+
+}

+ 22 - 0
sample-kudu/src/main/java/com/gyee/wisdom/samplekudu/util/AppCode.java

@@ -0,0 +1,22 @@
+package com.gyee.wisdom.samplekudu.util;
+
+import lombok.Getter;
+
+/**
+ * @description:
+ * @auther: Wanghs
+ * @date: 2022-07-03
+ */
+@Getter
+public enum AppCode implements StatusCode {
+    APP_ERROR(2000, "业务异常");
+
+
+    private int code;
+    private String msg;
+
+    AppCode(int code, String msg) {
+        this.code = code;
+        this.msg = msg;
+    }
+}

+ 15 - 0
sample-kudu/src/main/java/com/gyee/wisdom/samplekudu/util/ChineseDes.java

@@ -0,0 +1,15 @@
+package com.gyee.wisdom.samplekudu.util;
+
+import java.lang.annotation.*;
+
+/**
+ * @description:
+ * @auther: Wanghs
+ * @date: 2022-04-02
+ */
+@Documented
+@Retention(RetentionPolicy.RUNTIME)
+@Target(ElementType.FIELD)
+public @interface ChineseDes {
+    String value()default "";
+}

+ 90 - 0
sample-kudu/src/main/java/com/gyee/wisdom/samplekudu/util/CsvExportUtil.java

@@ -0,0 +1,90 @@
+package com.gyee.wisdom.samplekudu.util;
+
+import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
+
+import javax.servlet.http.HttpServletResponse;
+import java.io.OutputStream;
+import java.io.UnsupportedEncodingException;
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import java.util.List;
+/**
+ * @description:
+ * @auther: Wanghs
+ * @date: 2022-12-06
+ */
+public class CsvExportUtil {
+    /**
+     * CSV文件列分隔符
+     */
+    private static final String CSV_COLUMN_SEPARATOR = ",";
+
+    /**
+     * CSV文件行分隔符
+     */
+    private static final String CSV_ROW_SEPARATOR = "\r\n";
+
+    /**
+     * @param dataList 集合数据
+     * @param titles   表头部数据
+     * @param os       输出流
+     */
+    public static <T> void doExport(List<T> dataList, String[] titles, OutputStream os) throws Exception {
+        StringBuilder bud = new StringBuilder();
+        // 组装表头 如果传入的表头为null,则直接获取T的字段作为表头
+       if(titles==null){
+           Field[] declaredFields = dataList.get(0).getClass().getDeclaredFields();
+
+           titles=new String[declaredFields.length];
+
+           for (int i = 0; i < declaredFields.length; i++) {
+               titles[i]=declaredFields[i].getName();
+           }
+       }
+        for (String title : titles) {
+            bud.append(title).append(CSV_COLUMN_SEPARATOR);
+        }
+        bud.append(CSV_ROW_SEPARATOR);
+
+        // 组装数据
+        if (CollectionUtils.isNotEmpty(dataList)) {
+            for (Object obj : dataList) {
+                Field[] fields = obj.getClass().getDeclaredFields();
+                    for (Field field : fields) {
+
+                        String fieldName = field.getName();
+                        String getMethodStr_lcing = "get" + fieldName.substring(0, 1).toUpperCase() + fieldName.substring(1);
+                        Method getMethod_lcing = obj.getClass().getMethod(getMethodStr_lcing);
+                        Object value = getMethod_lcing.invoke(obj);
+                        if(value!=null)
+                            bud.append(value.toString());
+                        bud.append(CSV_COLUMN_SEPARATOR);
+                        continue;
+                    }
+                bud.append(CSV_ROW_SEPARATOR);
+            }
+        }
+
+        // 写出响应
+        os.write(bud.toString().getBytes("UTF-8")); //windows下防止中文乱码
+        os.flush();
+    }
+
+    /**
+     * 设置Header
+     *
+     * @param fileName
+     * @param response
+     * @throws UnsupportedEncodingException
+     */
+    public static void responseSetProperties(String fileName, HttpServletResponse response) throws UnsupportedEncodingException {
+        // 设置文件后缀
+        SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss");
+        String fn = fileName + sdf.format(new Date());
+        response.setContentType("application/octet-stream");
+        response.setContentType("application/vnd.ms-excel;charset=UTF-8");
+        response.setHeader("Content-Disposition","attachment;filename=\"" + fn + ".csv\"");
+    }
+}

+ 192 - 0
sample-kudu/src/main/java/com/gyee/wisdom/samplekudu/util/DateUtils.java

@@ -0,0 +1,192 @@
+package com.gyee.wisdom.samplekudu.util;
+
+import org.apache.commons.lang3.time.DateFormatUtils;
+
+import java.lang.management.ManagementFactory;
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.util.Calendar;
+import java.util.Date;
+
+/**
+ * 时间工具类
+ * 
+ * @author ruoyi
+ */
+public class DateUtils extends org.apache.commons.lang3.time.DateUtils
+{
+    public static String YYYY = "yyyy";
+
+    public static String YYYY_MM = "yyyy-MM";
+
+    public static String YYYY_MM_DD = "yyyy-MM-dd";
+
+    public static String YYYYMMDDHHMMSS = "yyyyMMddHHmmss";
+
+    public static String YYYY_MM_DD_HH_MM_SS = "yyyy-MM-dd HH:mm:ss";
+    
+    private static String[] parsePatterns = {
+            "yyyy-MM-dd", "yyyy-MM-dd HH:mm:ss", "yyyy-MM-dd HH:mm", "yyyy-MM", 
+            "yyyy/MM/dd", "yyyy/MM/dd HH:mm:ss", "yyyy/MM/dd HH:mm", "yyyy/MM",
+            "yyyy.MM.dd", "yyyy.MM.dd HH:mm:ss", "yyyy.MM.dd HH:mm", "yyyy.MM"};
+
+    /**
+     * 获取当前Date型日期
+     * 
+     * @return Date() 当前日期
+     */
+    public static Date getNowDate()
+    {
+        return new Date();
+    }
+
+    /**
+     * 获取当前日期, 默认格式为yyyy-MM-dd
+     * 
+     * @return String
+     */
+    public static String getDate()
+    {
+        return dateTimeNow(YYYY_MM_DD);
+    }
+
+    public static final String getTime()
+    {
+        return dateTimeNow(YYYY_MM_DD_HH_MM_SS);
+    }
+
+    public static final String dateTimeNow()
+    {
+        return dateTimeNow(YYYYMMDDHHMMSS);
+    }
+
+    public static final String dateTimeNow(final String format)
+    {
+        return parseDateToStr(format, new Date());
+    }
+
+    public static final String dateTime(final Date date)
+    {
+        return parseDateToStr(YYYY_MM_DD, date);
+    }
+
+    public static final String parseDateToStr(final String format, final Date date)
+    {
+        return new SimpleDateFormat(format).format(date);
+    }
+
+    public static final Date dateTime(final String format, final String ts)
+    {
+        try
+        {
+            return new SimpleDateFormat(format).parse(ts);
+        }
+        catch (ParseException e)
+        {
+            throw new RuntimeException(e);
+        }
+    }
+
+    /**
+     * 日期路径 即年/月/日 如2018/08/08
+     */
+    public static final String datePath()
+    {
+        Date now = new Date();
+        return DateFormatUtils.format(now, "yyyy/MM/dd");
+    }
+
+    /**
+     * 日期路径 即年/月/日 如20180808
+     */
+    public static final String dateTime()
+    {
+        Date now = new Date();
+        return DateFormatUtils.format(now, "yyyyMMdd");
+    }
+
+    /**
+     * 日期型字符串转化为日期 格式
+     */
+    public static Date parseDate(Object str)
+    {
+        if (str == null)
+        {
+            return null;
+        }
+        try
+        {
+            return parseDate(str.toString(), parsePatterns);
+        }
+        catch (ParseException e)
+        {
+            return null;
+        }
+    }
+    
+    /**
+     * 获取服务器启动时间
+     */
+    public static Date getServerStartDate()
+    {
+        long time = ManagementFactory.getRuntimeMXBean().getStartTime();
+        return new Date(time);
+    }
+    /**
+     * 获取当前扶助年份
+     *@return 年份
+     */
+    public  static  Integer getHelpYear(){
+        Calendar calendar = Calendar.getInstance();
+        int month = calendar.get(Calendar.MONTH) + 1;
+        //大于九月份 算第二年
+        if (month>=9){
+            return  calendar.get(Calendar.YEAR)+1;
+        }else {
+            return  calendar.get(Calendar.YEAR);
+        }
+    }
+    /**
+     * 获取变更数据查询时间
+     *@return 年月份
+     */
+    public  static  String getBgTime(){
+        Calendar calendar = Calendar.getInstance();
+        int month = calendar.get(Calendar.MONTH) + 1;
+        //大于等于九月份 取当年的九月份
+        if (month>=9){
+            return calendar.get(Calendar.YEAR)+"-09";
+        }else {
+            return calendar.get(Calendar.YEAR)-1+"-09";
+        }
+    }
+    /**
+     * 计算相差天数
+     */
+    public static int differentDaysByMillisecond(Date date1, Date date2)
+    {
+        return Math.abs((int) ((date2.getTime() - date1.getTime()) / (1000 * 3600 * 24)));
+    }
+
+    /**
+     * 计算两个时间差
+     */
+    public static String getDatePoor(Date endDate, Date nowDate)
+    {
+        long nd = 1000 * 24 * 60 * 60;
+        long nh = 1000 * 60 * 60;
+        long nm = 1000 * 60;
+        // long ns = 1000;
+        // 获得两个时间的毫秒时间差异
+        long diff = endDate.getTime() - nowDate.getTime();
+        // 计算差多少天
+        long day = diff / nd;
+        // 计算差多少小时
+        long hour = diff % nd / nh;
+        // 计算差多少分钟
+        long min = diff % nd % nh / nm;
+        // 计算差多少秒//输出结果
+        // long sec = diff % nd % nh % nm / ns;
+        return day + "天" + hour + "小时" + min + "分钟";
+    }
+}

+ 17 - 0
sample-kudu/src/main/java/com/gyee/wisdom/samplekudu/util/PassToken.java

@@ -0,0 +1,17 @@
+package com.gyee.wisdom.samplekudu.util;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * @descrition: 如果某一个restful接口不需要登陆验证,则controller使用这个注释
+ * @author:Wanghs
+ * @date:2020-05-21
+ */
+@Target({ElementType.METHOD, ElementType.TYPE})
+@Retention(RetentionPolicy.RUNTIME)
+public @interface PassToken {
+    boolean required() default true;
+}

+ 23 - 0
sample-kudu/src/main/java/com/gyee/wisdom/samplekudu/util/ResultCode.java

@@ -0,0 +1,23 @@
+package com.gyee.wisdom.samplekudu.util;
+
+import lombok.Getter;
+
+
+@Getter
+public enum ResultCode implements StatusCode{
+    SUCCESS(1000,"请求成功"),
+    FAILED(1001,"请求失败"),
+    VALIDATE_ERROR(1002,"参数校验失败"),
+    RESPONSE_PACK_ERROR(1003,"response返回包装失败"),
+    TAOS_CONDITION_ERROR(1004,"taos查询条件无效"),
+    TAOS_ERROR(1005,"taos查询异常"),
+    TAOS_DATATYPE_ERROR(1006,"taos数据类型异常"),
+    TAOS_DATA_CLEAN_ERROR(1007,"taos数据清洗异常");
+
+    private int code;
+    private String msg;
+     ResultCode(int code,String msg){
+        this.code=code;
+        this.msg=msg;
+    }
+}

+ 46 - 0
sample-kudu/src/main/java/com/gyee/wisdom/samplekudu/util/ResultVo.java

@@ -0,0 +1,46 @@
+package com.gyee.wisdom.samplekudu.util;
+
+import lombok.Data;
+
+import java.io.Serializable;
+
+
+@Data
+public class ResultVo implements Serializable {
+    // 状态码
+    private int code;
+
+    // 状态信息
+    private String msg;
+
+    // 返回对象
+    private Object data;
+
+    // 手动设置返回vo
+    public ResultVo(int code, String msg, Object data) {
+        this.code = code;
+        this.msg = msg;
+        this.data = data;
+    }
+
+    // 默认返回成功状态码,数据对象
+    public ResultVo(Object data) {
+        this.code = ResultCode.SUCCESS.getCode();
+        this.msg = ResultCode.SUCCESS.getMsg();
+        this.data = data;
+    }
+
+    // 返回指定状态码,数据对象
+    public ResultVo(StatusCode statusCode, Object data) {
+        this.code = statusCode.getCode();
+        this.msg = statusCode.getMsg();
+        this.data = data;
+    }
+
+    // 只返回状态码
+    public ResultVo(StatusCode statusCode) {
+        this.code = statusCode.getCode();
+        this.msg = statusCode.getMsg();
+        this.data = null;
+    }
+}

+ 161 - 0
sample-kudu/src/main/java/com/gyee/wisdom/samplekudu/util/SnowflakeGenerator.java

@@ -0,0 +1,161 @@
+package com.gyee.wisdom.samplekudu.util;
+
+/**
+ * Twitter_Snowflake<br>
+ * SnowFlake的结构如下(每部分用-分开):<br>
+ * 0 - 0000000000 0000000000 0000000000 0000000000 0 - 00000 - 00000 - 000000000000 <br>
+ * 1位标识,由于long基本类型在Java中是带符号的,最高位是符号位,正数是0,负数是1,所以id一般是正数,最高位是0<br>
+ * 41位时间截(毫秒级),注意,41位时间截不是存储当前时间的时间截,而是存储时间截的差值(当前时间截 - 开始时间截)
+ * 得到的值),这里的的开始时间截,一般是我们的id生成器开始使用的时间,由我们程序来指定的(如下下面程序IdWorker类的startTime属性)。41位的时间截,可以使用69年,年T = (1L << 41) / (1000L * 60 * 60 * 24 * 365) = 69<br>
+ * 10位的数据机器位,可以部署在1024个节点,包括5位datacenterId和5位workerId<br>
+ * 12位序列,毫秒内的计数,12位的计数顺序号支持每个节点每毫秒(同一机器,同一时间截)产生4096个ID序号<br>
+ * 加起来刚好64位,为一个Long型。<br>
+ * SnowFlake的优点是,整体上按照时间自增排序,并且整个分布式系统内不会产生ID碰撞(由数据中心ID和机器ID作区分),并且效率较高,经测试,SnowFlake每秒能够产生26万ID左右。
+ */
+public class SnowflakeGenerator {
+
+    // ==============================Fields===========================================
+    /** 开始时间截 (2015-01-01) */
+    private final long twepoch = 1420041600000L;
+
+    /** 机器id所占的位数 */
+    private final long workerIdBits = 5L;
+
+    /** 数据标识id所占的位数 */
+    private final long datacenterIdBits = 5L;
+
+    /** 支持的最大机器id,结果是31 (这个移位算法可以很快的计算出几位二进制数所能表示的最大十进制数) */
+    private final long maxWorkerId = -1L ^ (-1L << workerIdBits);
+
+    /** 支持的最大数据标识id,结果是31 */
+    private final long maxDatacenterId = -1L ^ (-1L << datacenterIdBits);
+
+    /** 序列在id中占的位数 */
+    private final long sequenceBits = 12L;
+
+    /** 机器ID向左移12位 */
+    private final long workerIdShift = sequenceBits;
+
+    /** 数据标识id向左移17位(12+5) */
+    private final long datacenterIdShift = sequenceBits + workerIdBits;
+
+    /** 时间截向左移22位(5+5+12) */
+    private final long timestampLeftShift = sequenceBits + workerIdBits + datacenterIdBits;
+
+    /** 生成序列的掩码,这里为4095 (0b111111111111=0xfff=4095) */
+    private final long sequenceMask = -1L ^ (-1L << sequenceBits);
+
+    /** 工作机器ID(0~31) */
+    private long workerId;
+
+    /** 数据中心ID(0~31) */
+    private long datacenterId;
+
+    /** 毫秒内序列(0~4095) */
+    private long sequence = 0L;
+
+    /** 上次生成ID的时间截 */
+    private long lastTimestamp = -1L;
+
+    //==============================Constructors=====================================
+    /**
+     * 构造函数
+     * @param workerId 工作ID (0~31)
+     * @param datacenterId 数据中心ID (0~31)
+     */
+    public SnowflakeGenerator(long workerId, long datacenterId) {
+        if (workerId > maxWorkerId || workerId < 0) {
+            throw new IllegalArgumentException(String.format("worker Id can't be greater than %d or less than 0", maxWorkerId));
+        }
+        if (datacenterId > maxDatacenterId || datacenterId < 0) {
+            throw new IllegalArgumentException(String.format("datacenter Id can't be greater than %d or less than 0", maxDatacenterId));
+        }
+        this.workerId = workerId;
+        this.datacenterId = datacenterId;
+    }
+
+    // ==============================Methods==========================================
+    /**
+     * 获得下一个ID (该方法是线程安全的)
+     * @return SnowflakeId
+     */
+    public synchronized long nextId() {
+        long timestamp = timeGen();
+
+        //如果当前时间小于上一次ID生成的时间戳,说明系统时钟回退过这个时候应当抛出异常
+        if (timestamp < lastTimestamp) {
+            throw new RuntimeException(
+                    String.format("Clock moved backwards.  Refusing to generate id for %d milliseconds", lastTimestamp - timestamp));
+        }
+
+        //如果是同一时间生成的,则进行毫秒内序列
+        if (lastTimestamp == timestamp) {
+            sequence = (sequence + 1) & sequenceMask;
+            //毫秒内序列溢出
+            if (sequence == 0) {
+                //阻塞到下一个毫秒,获得新的时间戳
+                timestamp = tilNextMillis(lastTimestamp);
+            }
+        }
+        //时间戳改变,毫秒内序列重置
+        else {
+            sequence = 0L;
+        }
+
+        //上次生成ID的时间截
+        lastTimestamp = timestamp;
+
+        //移位并通过或运算拼到一起组成64位的ID
+        return ((timestamp - twepoch) << timestampLeftShift) //
+                | (datacenterId << datacenterIdShift) //
+                | (workerId << workerIdShift) //
+                | sequence;
+    }
+
+    /**
+     * 阻塞到下一个毫秒,直到获得新的时间戳
+     * @param lastTimestamp 上次生成ID的时间截
+     * @return 当前时间戳
+     */
+    protected long tilNextMillis(long lastTimestamp) {
+        long timestamp = timeGen();
+        while (timestamp <= lastTimestamp) {
+            timestamp = timeGen();
+        }
+        return timestamp;
+    }
+
+    /**
+     * 返回以毫秒为单位的当前时间
+     * @return 当前时间(毫秒)
+     */
+    protected long timeGen() {
+        return System.currentTimeMillis();
+    }
+
+
+    private static SnowflakeGenerator idWorker = null;
+
+    public synchronized static SnowflakeGenerator getIdWorker() {
+
+        if (idWorker == null)
+            idWorker = new SnowflakeGenerator(2, 3);
+
+        return idWorker;
+    }
+
+    public static long generateId() {
+        //if (idWorker == null)
+            //idWorker = new SnowflakeGenerator(0, 0);
+
+        //return idWorker.nextId();
+        SnowflakeGenerator snowflakeGenerator = getIdWorker();
+
+        return snowflakeGenerator.nextId();
+//        for (int i = 0; i < 1000; i++) {
+//            long id = idWorker.nextId();
+//            System.out.println(Long.toBinaryString(id));
+//            System.out.println(id);
+//        }
+    }
+}

+ 113 - 0
sample-kudu/src/main/java/com/gyee/wisdom/samplekudu/util/SpringContextUtil.java

@@ -0,0 +1,113 @@
+package com.gyee.wisdom.samplekudu.util;
+
+import org.springframework.beans.BeansException;
+import org.springframework.beans.factory.DisposableBean;
+import org.springframework.beans.factory.NoSuchBeanDefinitionException;
+import org.springframework.context.ApplicationContext;
+import org.springframework.context.ApplicationContextAware;
+import org.springframework.stereotype.Component;
+
+/**
+ * Spring的工具类,用来获得配置文件中的bean
+ * 
+ */
+@Component
+public class SpringContextUtil implements ApplicationContextAware, DisposableBean {
+
+	private static ApplicationContext applicationContext = null;
+
+	/***
+	 * 当继承了ApplicationContextAware类之后,那么程序在调用 getBean(String)的时候会自动调用该方法, 不用自己操作
+	 */
+	@Override
+	public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
+		SpringContextUtil.applicationContext = applicationContext;
+	}
+
+	/**
+	 * 实现DisposableBean接口, 在Context关闭时清理静态变量.
+	 */
+	@Override
+	public void destroy() throws Exception {
+		SpringContextUtil.clearHolder();
+	}
+
+	/**
+	 * 取得存储在静态变量中的ApplicationContext.
+	 */
+	public static ApplicationContext getApplicationContext() {
+		return applicationContext;
+	}
+
+	/***
+	 * 根据一个bean的id获取配置文件中相应的bean
+	 * 
+	 * @param name
+	 * @return
+	 * @throws BeansException
+	 */
+	@SuppressWarnings("unchecked")
+	public static <T> T getBean(String name) throws BeansException {
+		return (T) applicationContext.getBean(name);
+	}
+
+	/***
+	 * 类似于getBean(String name)只是在参数中提供了需要返回到的类型。
+	 * 
+	 * @param requiredType
+	 * @return
+	 * @throws BeansException
+	 */
+	public static <T> T getBean(Class<T> requiredType) throws BeansException {
+		return applicationContext.getBean(requiredType);
+	}
+
+	/**
+	 * 如果BeanFactory包含一个与所给名称匹配的bean定义,则返回true
+	 * 
+	 * @param name
+	 * @return boolean
+	 */
+	public static boolean containsBean(String name) {
+		return applicationContext.containsBean(name);
+	}
+
+	/**
+	 * 判断以给定名字注册的bean定义是一个singleton还是一个prototype。
+	 * 如果与给定名字相应的bean定义没有被找到,将会抛出一个异常(NoSuchBeanDefinitionException)
+	 * 
+	 * @param name
+	 * @return boolean
+	 * @throws NoSuchBeanDefinitionException
+	 */
+	public static boolean isSingleton(String name) throws NoSuchBeanDefinitionException {
+		return applicationContext.isSingleton(name);
+	}
+
+	/**
+	 * @param name
+	 * @return Class 注册对象的类型
+	 * @throws NoSuchBeanDefinitionException
+	 */
+	public static Class<?> getType(String name) throws NoSuchBeanDefinitionException {
+		return applicationContext.getType(name);
+	}
+
+	/**
+	 * 如果给定的bean名字在bean定义中有别名,则返回这些别名
+	 * 
+	 * @param name
+	 * @return
+	 * @throws NoSuchBeanDefinitionException
+	 */
+	public static String[] getAliases(String name) throws NoSuchBeanDefinitionException {
+		return applicationContext.getAliases(name);
+	}
+
+	/**
+	 * 清除SpringContextHolder中的ApplicationContext为Null.
+	 */
+	public static void clearHolder() {
+		applicationContext = null;
+	}
+}

+ 7 - 0
sample-kudu/src/main/java/com/gyee/wisdom/samplekudu/util/StatusCode.java

@@ -0,0 +1,7 @@
+package com.gyee.wisdom.samplekudu.util;
+
+public interface StatusCode {
+    int getCode();
+    String getMsg();
+
+}

+ 530 - 0
sample-kudu/src/main/java/com/gyee/wisdom/samplekudu/util/StringUtil.java

@@ -0,0 +1,530 @@
+package com.gyee.wisdom.samplekudu.util;
+
+
+
+import java.math.BigDecimal;
+import java.math.RoundingMode;
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.util.*;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+
+/**
+ * 字符串工具类
+ * 
+ * @author fc
+ */
+public class StringUtil extends org.apache.commons.lang3.StringUtils
+{
+    /** 空字符串 */
+    private static final String NULLSTR = "";
+
+    /** 下划线 */
+    private static final char SEPARATOR = '_';
+
+    /**
+     * 获取参数不为空值
+     * 
+     * @param value defaultValue 要判断的value
+     * @return value 返回值
+     */
+    public static <T> T nvl(T value, T defaultValue)
+    {
+        return value != null ? value : defaultValue;
+    }
+
+    /**
+     * * 判断一个Collection是否为空, 包含List,Set,Queue
+     * 
+     * @param coll 要判断的Collection
+     * @return true:为空 false:非空
+     */
+    public static boolean isEmpty(Collection<?> coll)
+    {
+        return isNull(coll) || coll.isEmpty();
+    }
+
+    /**
+     * * 判断一个Collection是否非空,包含List,Set,Queue
+     * 
+     * @param coll 要判断的Collection
+     * @return true:非空 false:空
+     */
+    public static boolean isNotEmpty(Collection<?> coll)
+    {
+        return !isEmpty(coll);
+    }
+    public static int roundToInt(double num) {
+
+        return new BigDecimal(num).setScale(0, RoundingMode.HALF_UP).intValue();
+    }
+    /**
+     * * 判断一个对象数组是否为空
+     * 
+     * @param objects 要判断的对象数组
+     ** @return true:为空 false:非空
+     */
+    public static boolean isEmpty(Object[] objects)
+    {
+        return isNull(objects) || (objects.length == 0);
+    }
+
+    /**
+     * * 判断一个对象数组是否非空
+     * 
+     * @param objects 要判断的对象数组
+     * @return true:非空 false:空
+     */
+    public static boolean isNotEmpty(Object[] objects)
+    {
+        return !isEmpty(objects);
+    }
+
+    /**
+     * * 判断一个Map是否为空
+     * 
+     * @param map 要判断的Map
+     * @return true:为空 false:非空
+     */
+    public static boolean isEmpty(Map<?, ?> map)
+    {
+        return isNull(map) || map.isEmpty();
+    }
+
+    /**
+     * * 判断一个Map是否为空
+     * 
+     * @param map 要判断的Map
+     * @return true:非空 false:空
+     */
+    public static boolean isNotEmpty(Map<?, ?> map)
+    {
+        return !isEmpty(map);
+    }
+
+    /**
+     * * 判断一个字符串是否为空串
+     * 
+     * @param str String
+     * @return true:为空 false:非空
+     */
+    public static boolean isEmpty(String str)
+    {
+        return isNull(str) || NULLSTR.equals(str.trim());
+    }
+
+    /**
+     * * 判断一个字符串是否为非空串
+     * 
+     * @param str String
+     * @return true:非空串 false:空串
+     */
+    public static boolean isNotEmpty(String str)
+    {
+        return !isEmpty(str);
+    }
+
+    /**
+     * * 判断一个对象是否为空
+     * 
+     * @param object Object
+     * @return true:为空 false:非空
+     */
+    public static boolean isNull(Object object)
+    {
+        return object == null;
+    }
+
+    /**
+     * * 判断一个对象是否非空
+     * 
+     * @param object Object
+     * @return true:非空 false:空
+     */
+    public static boolean isNotNull(Object object)
+    {
+        return !isNull(object);
+    }
+
+    /**
+     * * 判断一个对象是否是数组类型(Java基本型别的数组)
+     * 
+     * @param object 对象
+     * @return true:是数组 false:不是数组
+     */
+    public static boolean isArray(Object object)
+    {
+        return isNotNull(object) && object.getClass().isArray();
+    }
+
+    /**
+     * 去空格
+     */
+    public static String trim(String str)
+    {
+        return (str == null ? "" : str.trim());
+    }
+
+    /**
+     * 截取字符串
+     * 
+     * @param str 字符串
+     * @param start 开始
+     * @return 结果
+     */
+    public static String substring(final String str, int start)
+    {
+        if (str == null)
+        {
+            return NULLSTR;
+        }
+
+        if (start < 0)
+        {
+            start = str.length() + start;
+        }
+
+        if (start < 0)
+        {
+            start = 0;
+        }
+        if (start > str.length())
+        {
+            return NULLSTR;
+        }
+
+        return str.substring(start);
+    }
+
+    /**
+     * 截取字符串
+     * 
+     * @param str 字符串
+     * @param start 开始
+     * @param end 结束
+     * @return 结果
+     */
+    public static String substring(final String str, int start, int end)
+    {
+        if (str == null)
+        {
+            return NULLSTR;
+        }
+
+        if (end < 0)
+        {
+            end = str.length() + end;
+        }
+        if (start < 0)
+        {
+            start = str.length() + start;
+        }
+
+        if (end > str.length())
+        {
+            end = str.length();
+        }
+
+        if (start > end)
+        {
+            return NULLSTR;
+        }
+
+        if (start < 0)
+        {
+            start = 0;
+        }
+        if (end < 0)
+        {
+            end = 0;
+        }
+
+        return str.substring(start, end);
+    }
+
+
+
+
+    /**
+     * 驼峰命名转下划线 nameVc>>name_vc
+     */
+    public static String toUnderScoreCase(String s)
+    {
+        if (s == null)
+        {
+            return null;
+        }
+        StringBuilder sb = new StringBuilder();
+        boolean upperCase = false;
+        for (int i = 0; i < s.length(); i++)
+        {
+            char c = s.charAt(i);
+
+            boolean nextUpperCase = true;
+
+            if (i < (s.length() - 1))
+            {
+                nextUpperCase = Character.isUpperCase(s.charAt(i + 1));
+            }
+
+            if ((i > 0) && Character.isUpperCase(c))
+            {
+                if (!upperCase || !nextUpperCase)
+                {
+                    sb.append(SEPARATOR);
+                }
+                upperCase = true;
+            }
+            else
+            {
+                upperCase = false;
+            }
+
+            sb.append(Character.toLowerCase(c));
+        }
+
+        return sb.toString();
+    }
+
+    /**
+     * 是否包含字符串
+     * 
+     * @param str 验证字符串
+     * @param strs 字符串组
+     * @return 包含返回true
+     */
+    public static boolean inStringIgnoreCase(String str, String... strs)
+    {
+        if (str != null && strs != null)
+        {
+            for (String s : strs)
+            {
+                if (str.equalsIgnoreCase(trim(s)))
+                {
+                    return true;
+                }
+            }
+        }
+        return false;
+    }
+   
+    
+    /**
+     * 将下划线大写方式命名的字符串转换为驼峰式。如果转换前的下划线大写方式命名的字符串为空,则返回空字符串。 例如:HELLO_WORLD->HelloWorld
+     * 
+     * @param name 转换前的下划线大写方式命名的字符串
+     * @return 转换后的驼峰式命名的字符串
+     */
+    public static String convertToCamelCase(String name)
+    {
+        StringBuilder result = new StringBuilder();
+        // 快速检查
+        if (name == null || name.isEmpty())
+        {
+            // 没必要转换
+            return "";
+        }
+        else if (!name.contains("_"))
+        {
+            // 不含下划线,仅将首字母大写
+            return name.substring(0, 1).toUpperCase() + name.substring(1);
+        }
+        // 用下划线将原始字符串分割
+        String[] camels = name.split("_");
+        for (String camel : camels)
+        {
+            // 跳过原始字符串中开头、结尾的下换线或双重下划线
+            if (camel.isEmpty())
+            {
+                continue;
+            }
+            // 首字母大写
+            result.append(camel.substring(0, 1).toUpperCase());
+            result.append(camel.substring(1).toLowerCase());
+        }
+        return result.toString();
+    }
+    /**
+     * 首字母大写
+     *
+     * @param name
+     * @return
+     */
+    public static String firstUpperCase(String name) {
+        name = name.substring(0, 1).toUpperCase() + name.substring(1);
+        return name;
+    }
+    /**
+     * 首字母小写
+     *
+     * @param name
+     * @return
+     */
+    public static String firstLowerCase(String name) {
+        name = name.substring(0, 1).toLowerCase() + name.substring(1);
+        return name;
+
+    }
+    
+    /**
+     * 将下划线转化为大写
+     *
+     * @param name
+     * @param firstCase 首字母是否大写 true:大写 false;小写
+     * @return
+     */
+    public static String upperCase_(String name, boolean firstCase) {
+        if(isEmpty(name)){
+            return "";
+        }
+        String[] s = name.split("_");
+        StringBuffer stringBuffer = new StringBuffer();
+        for (String s1 : s) {
+            stringBuffer.append(s1.substring(0, 1).toUpperCase() + s1.substring(1));
+        }
+        if(!firstCase){
+            return firstLowerCase(stringBuffer.toString());
+        }
+        return stringBuffer.toString();
+    }
+    
+    /**
+     * get方法名字转成 t_b_abc>>tBAbc
+     * @param str
+     * @return
+     * @author gyee
+     * @Date 2020年1月30日 下午11:55:54
+     */
+    public static String toFUNName(String str) {
+    	StringBuffer buffer=new StringBuffer();
+    	String name=str;
+    	if(name.contains("_")) {
+    		// 用下划线将原始字符串分割
+            String[] camels = name.split("_");
+            boolean b=true;
+            
+            for (String str1 : camels) {
+            	if(str1.length()==1&&b) {
+            		b=false;
+            		buffer.append(str1);
+            	}else {
+            		buffer.append(StringUtil.firstUpperCase(str1));
+            	}
+				
+			}
+    	}else {
+    		buffer.append(StringUtil.firstUpperCase(name));
+    	}
+		return buffer.toString();
+    }
+
+
+    /**
+     * 是否不为空串
+     *
+     * @param obj
+     * @return
+     */
+    public static boolean notEmp(Object obj) {
+        return !empty(obj);
+    }
+
+    /**
+     * 是否为空串
+     *
+     * @param obj
+     * @return
+     */
+    public static boolean empty(Object obj) {
+        if (obj == null)
+            return true;
+        String str;
+        if (obj instanceof String) {
+            str = (String) obj;
+        } else {
+            str = obj.toString();
+        }
+        return str.length() == 0;
+    }
+
+    public static double round(double num, int digit) {
+
+        return new BigDecimal(num).setScale(digit, RoundingMode.HALF_UP).doubleValue();
+    }
+    /**
+     * 将字符串解析为Date类型
+     *
+     * @param date
+     * @param pattern
+     * @return
+     */
+    public static Date toDate(String date, String pattern) {
+        SimpleDateFormat format = new SimpleDateFormat(pattern);
+        try {
+            return format.parse(date);
+        } catch (ParseException e) {
+            throw new RuntimeException(String.format("Failed to parse the String [%s] to Date.", date), e);
+        }
+    }
+    /**
+     *
+     * @方法名称: getUUID
+     * @描述: 获得UUID
+     * @参数 @return
+     * @返回值 String
+     * @抛出异常
+     */
+    public static String getUUID() {
+        String s = UUID.randomUUID().toString();
+        // 去掉“-”符号
+        return s.substring(0, 8) + s.substring(9, 13) + s.substring(14, 18) + s.substring(19, 23) + s.substring(24);
+    }
+
+    /**
+     * 判断是否为数字字符串
+     * @param str
+     * @return
+     */
+    public static boolean isNumeric(String str){
+        Pattern pattern = Pattern.compile("^(-?\\d+)(\\.\\d+)?$");
+        if(notEmp(str))
+        {
+            Matcher isNum = pattern.matcher(str);
+            if( !isNum.matches() ){
+                return false;
+            }
+
+        }else
+        {
+            return false;
+        }
+
+        return true;
+    }
+
+
+    /**
+     * 正则表达式
+     * @param input     需要匹配的字符串
+     * @param expression 正则表达公式
+     * @return
+     */
+    public static List<String> pattern(String input, String expression){
+        // 创建 Pattern 对象
+        Pattern p = Pattern.compile(expression);
+        Matcher m = p.matcher(input);
+
+        ArrayList list = new ArrayList();
+        while (m.find()) {
+            list.add(m.group(0));
+        }
+        //去除重复值
+        HashSet hs=new HashSet(list);
+        list.clear();
+        list.addAll(hs);
+
+        return list;
+    }
+}

+ 35 - 0
sample-kudu/src/main/java/com/gyee/wisdom/samplekudu/util/TimeService.java

@@ -0,0 +1,35 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.gyee.wisdom.samplekudu.util;
+
+/**
+ * Time service.
+ * 
+ * @author zhangliang
+ */
+public class TimeService {
+    
+    /**
+     * Get current millis.
+     * 
+     * @return current millis
+     */
+    public long getCurrentMillis() {
+        return System.currentTimeMillis();
+    }
+}

+ 8 - 0
sample-kudu/src/main/java/com/gyee/wisdom/samplekudu/util/UUIDUtil.java

@@ -0,0 +1,8 @@
+package com.gyee.wisdom.samplekudu.util;
+
+import java.util.UUID;
+
+public class UUIDUtil {
+
+    public static String Uuid= UUID.randomUUID().toString().replaceAll("_","");
+}

+ 17 - 0
sample-kudu/src/main/java/com/gyee/wisdom/samplekudu/util/UserLoginToken.java

@@ -0,0 +1,17 @@
+package com.gyee.wisdom.samplekudu.util;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * @descrition:如果某一个restful接口需要登陆验证,则controller使用这个注释
+ * @author:Wanghs
+ * @date:2020-05-21
+ */
+@Target({ElementType.METHOD, ElementType.TYPE})
+@Retention(RetentionPolicy.RUNTIME)
+public @interface UserLoginToken {
+    boolean required() default true;
+}

+ 101 - 0
sample-kudu/src/main/resources/application.yml

@@ -0,0 +1,101 @@
+server:
+  port: 8099
+  max-http-header-size: 128KB
+  servlet:
+    encoding:
+      charset: UTF-8
+      enabled: true
+      force: true
+spring:
+  application:
+    name: sample-kudu
+  datasource:
+    driver-class-name: org.postgresql.Driver
+    url: jdbc:postgresql://18.6.30.71:5432/wisdom_cs
+    username: postgres
+    password: gdnxfd123
+    type: com.alibaba.druid.pool.DruidDataSource
+
+
+mybatis-plus:
+  typeAliasesPackage: com.gyee.wisdom.alarm.samplekudu.entity
+  mapper-locations: classpath:mappers/*.xml
+  global-config:
+    #主键类型  0:"数据库ID自增", 1:"用户输入ID",2:"全局唯一ID (数字类型唯一ID)", 3:"全局唯一ID UUID";
+    id-type: 3
+    #字段策略 0:"忽略判断",1:"非 NULL 判断"),2:"非空判断"
+    field-strategy: 2
+    #驼峰下划线转换
+    db-column-underline: true
+    #mp2.3+ 全局表前缀 mp_
+    #table-prefix: mp_
+    #刷新mapper 调试神器
+    #refresh-mapper: true
+    #数据库大写下划线转换
+    #capital-mode: true
+    # Sequence序列接口实现类配置
+    key-generator: com.baomidou.mybatisplus.incrementer.OracleKeyGenerator
+    #逻辑删除配置(下面3个配置)
+    logic-delete-value: 1
+    logic-not-delete-value: 0
+    #sql-injector: com.baomidou.mybatisplus.mapper.LogicSqlInjector
+    #自定义填充策略接口实现
+    #meta-object-handler: com.baomidou.springboot.MyMetaObjectHandler
+  configuration:
+    #配置返回数据库(column下划线命名&&返回java实体是驼峰命名),自动匹配无需as(没开启这个,SQL需要写as: select user_id as userId)
+    map-underscore-to-camel-case: true
+    cache-enabled: false
+    #配置JdbcTypeForNull, oracle数据库必须配置
+    jdbc-type-for-null: 'null'
+    callSettersOnNulls: true
+
+logging:
+  level:
+    com:
+      gyee:
+        wisdom:
+          alarm:
+            sharding:
+              mapper: debug
+              service: info
+
+taos:
+  server_ip: 18.6.30.75
+  server_port: 6041
+  db_name: gdnxxny
+  user_name: root
+  password: taosdata
+  pool_size: 10
+  max_pool_size: 100
+  #driver_type: com.taosdata.jdbc.TSDBDriver
+  driver_type: com.taosdata.jdbc.rs.RestfulDriver
+  distinguish_case: true
+#kudu_master: manager1.prd.nxd1.com,manager1.prd.nxd1.com:21050
+kudu_master: manager1.prd.nxd1.com
+
+kudu_lcing_sample_table: impala::gyee_sample_kudu.lcing_sample
+
+calculate:
+  config:
+    #服务地址  ws://localhost:8011/wisdom
+    serviceUrl: http://18.6.30.71:8011/ts
+    #服务地址  ws://localhost:8011/wisdom
+    shardingServiceUrl: http://18.6.30.71:8075
+    #扫描线程轮询时间(单位:毫秒)
+    readThreadInterval: 1000
+    #计算线程轮询时间(单位:毫秒)
+    calcThreadInterval: 1000
+    #规则解析线程池大小
+    maxThreadCount: 4
+
+lcing:
+  station_id: XS_FDC
+  #差值率
+  sub_percent: 20
+  #覆冰计算周期 单位 秒
+  calc_cycle: 600
+  uniformcodes:
+    #AI056-舱外温度,AI025-10分钟风速,AI130-变频器有功功率,DI058-并网状态,
+    UP97: AI056,AI025,AI130,DI058,LLGL
+    #AI056-舱外温度,AI372-长期风速,AI130-pcs有功功率,DI1885--发电状态
+    UP105: AI056,AI372,AI130,DI1885,LLGL

+ 35 - 0
sample-kudu/src/main/resources/readme.md

@@ -0,0 +1,35 @@
+#样本数据抽取
+##叶片覆冰
+####数据要求:
+* 数据来源为TD
+* 导入样本库的数据需要进行时间对齐
+* 排除偏航动作中的数据
+* 排除启动,上电,停机,限电等过程状态的数据
+* 排除解缆动作过程中的数据
+
+
+
+|字段名| 描述   | 数据类型   |
+|---|------|--------|
+id|      | long   |
+stationid| 场站编号 | string |
+windturbineid| 风机编号 | string |
+model| 风机型号 | string |
+wind_speed| 风速   | double |
+impeller_speed| 叶轮转速 | double |
+blade_angle1| 桨距角1 | double |
+blade_angle2| 桨距角2 | double |
+blade_angle3| 桨距角3 | double |
+yaw_deviation| 偏航误差 | double |
+power|功率| double |
+torque|转矩| double |
+wind_direction| 风向   | double |
+room_position| 机舱位置 | double |
+timestamp|时间戳| long   |
+
+
+
+
+
+
+

+ 1 - 0
sample-kudu/src/main/resources/sql/lcing_sample.sql

@@ -0,0 +1 @@
+create table lcing_sample (  id bigint, station_id varchar, windturbine_id varchar,model varchar, wind_speed double, impeller_speed double,blade_angle1 double,blade_angle2 double,blade_angle3 double,yaw_deviation double,power double,torque double,wind_direction double,room_position double,correct_sample boolean,ts bigint,primary key (id) )stored as kudu;

+ 323 - 0
sample-kudu/src/test/java/com/gyee/wisdom/samplekudu/MyTest.java

@@ -0,0 +1,323 @@
+package com.gyee.wisdom.samplekudu;
+
+import com.gyee.wisdom.samplekudu.domain.data.LcingTagNameData;
+import com.gyee.wisdom.samplekudu.domain.input.InputLcing;
+import com.gyee.wisdom.samplekudu.entity.TsPointEntity;
+import com.gyee.wisdom.samplekudu.timeseries.DoubleTsData;
+import com.gyee.wisdom.samplekudu.timeseries.TsData;
+import com.gyee.wisdom.samplekudu.util.StringUtil;
+import org.apache.kudu.ColumnSchema;
+import org.apache.kudu.Schema;
+import org.apache.kudu.Type;
+import org.apache.kudu.client.*;
+import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.Tag;
+import org.junit.jupiter.api.Test;
+import org.springframework.boot.test.context.SpringBootTest;
+
+import java.lang.reflect.Field;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.sql.SQLOutput;
+import java.util.*;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
+
+/**
+ * @description:
+ * @auther: Wanghs
+ * @date: 2022-11-21
+ */
+
+@SpringBootTest
+public class MyTest {
+
+    @Test
+    public void test123() {
+        System.out.printf("123");
+    }
+
+    private KuduClient kuduClient;
+    private String kuduMaster;
+    private String tableName;
+
+
+    public void init() {
+        kuduMaster = "manager1.prd.nxd1.com,21050";
+
+        KuduClient.KuduClientBuilder kuduClientBuilder = new KuduClient.KuduClientBuilder(kuduMaster);
+
+        kuduClientBuilder.defaultSocketReadTimeoutMs(10000);
+        kuduClient = kuduClientBuilder.build();
+    }
+
+
+    @Test
+    public void testCreateTable() throws KuduException {
+
+        //port 21050
+        //manager1.prd.nxd1.com
+        tableName = "impala::gyee_sample_kudu.wanghs_test";
+        init();
+        DeleteTableResponse deleteTableResponse = kuduClient.deleteTable(tableName);
+
+        if (!kuduClient.tableExists(tableName)) {
+            ArrayList<ColumnSchema> columnSchemas = new ArrayList<>();
+            columnSchemas.add(new ColumnSchema.ColumnSchemaBuilder("id", Type.INT32).key(true).build());
+            columnSchemas.add(new ColumnSchema.ColumnSchemaBuilder("name", Type.STRING).build());
+            columnSchemas.add(new ColumnSchema.ColumnSchemaBuilder("date", Type.UNIXTIME_MICROS).build());//日期待定
+            columnSchemas.add(new ColumnSchema.ColumnSchemaBuilder("money", Type.DOUBLE).build());//小数待定
+            Schema schema = new Schema(columnSchemas);
+
+            CreateTableOptions options = new CreateTableOptions();
+            List<String> partitionList = new ArrayList<>();
+            //kudu表的分区字段是什么 TODO
+            partitionList.add("id");
+            //按照id.hashcode % 分区数 = 分区号
+            options.addHashPartitions(partitionList, 6);
+
+            //  kuduClient.createTable(tableName, schema, options);
+
+            System.out.println("123");
+        }
+    }
+
+
+    @Test
+    public void insert() throws KuduException {
+
+        init();
+        KuduSession kuduSession = kuduClient.newSession();
+
+        kuduSession.setFlushMode(SessionConfiguration.FlushMode.AUTO_FLUSH_SYNC);
+        KuduTable userTable = kuduClient.openTable("impala::gyee_sample_kudu.wanghs_test");
+        for (int i = 201; i <= 300; i++) {
+
+            Insert insert = userTable.newInsert();
+            PartialRow row = insert.getRow();
+            row.addInt("id", i);
+            row.addString("name", "wang" + i);
+
+            OperationResponse apply = kuduSession.apply(insert);
+            System.out.println(apply.getWriteTimestampRaw());
+        }
+    }
+
+    @Test
+    public void query() throws KuduException {
+        KuduScanner.KuduScannerBuilder kuduScannerBuilder = kuduClient
+                .newScannerBuilder(kuduClient.openTable(tableName));
+        List<String> columns = Arrays.asList("id", "name", "moeny");
+        kuduScannerBuilder.setProjectedColumnNames(columns);
+        KuduScanner kuduScanner = kuduScannerBuilder.build();
+        while (kuduScanner.hasMoreRows()) {
+            RowResultIterator rowResults = kuduScanner.nextRows();
+            while (rowResults.hasNext()) {
+                RowResult row = rowResults.next();
+//                new StringBuffer("id={},name={},money={}",
+//                        row.getInt("id"),
+//                        row.getString("name"),
+//                        row.getDouble("money"));
+                String outStr = "id=" + row.getInt("id") + "name=" + row.getString("name") + "money=" + row.getDouble("money");
+
+                System.out.println(outStr);
+            }
+        }
+    }
+
+    @Test
+    public void update() throws KuduException {
+        KuduSession kuduSession = kuduClient.newSession();
+        kuduSession.setFlushMode(SessionConfiguration.FlushMode.AUTO_FLUSH_SYNC);
+        KuduTable kuduTable = kuduClient.openTable(tableName);
+
+//        Update update = kuduTable.newUpdate();
+        //id存在就修改,不存在就新增
+        Upsert upsert = kuduTable.newUpsert();
+        PartialRow row = upsert.getRow();
+        row.addInt("id", 100000);
+        row.addString("name", "yangege");
+        row.addDouble("money", 100.222);
+        kuduSession.apply(upsert);
+    }
+
+    @Test
+    public void test() throws IllegalAccessException, InvocationTargetException, NoSuchMethodException {
+
+        LcingTagNameData data = new LcingTagNameData();
+
+        InputLcing lcing = new InputLcing();
+
+        lcing.setWindturbineStatusUniformCode("FJZT8");
+        lcing.setWindSpeedUniformCode("AI007");
+
+        Field[] lcingFieldArrays = lcing.getClass().getDeclaredFields();
+        for (Field field :
+                lcingFieldArrays) {
+            String name = field.getName();
+
+            String getMethodStr = "get" + name.substring(0, 1).toUpperCase() + name.substring(1);
+            Method getMethod = lcing.getClass().getMethod(getMethodStr);
+            String fieldValue = (String) getMethod.invoke(lcing);
+
+            String tagName = "";
+            if (StringUtil.isNotBlank(fieldValue)) {
+                if (fieldValue.equals("FJZT8"))
+                    tagName = "NX_FD_FJ_AI001";
+                else
+                    tagName = "NX_FD_FJ_AI007";
+            }
+
+
+            String setMethodStr = "set" + name.substring(0, 1).toUpperCase() + name.substring(1);
+            String replace = setMethodStr.replace("UniformCode", "TagName");
+
+            Method setMethod = data.getClass().getMethod(replace, String.class);
+            setMethod.invoke(data, tagName);
+        }
+
+        return;
+    }
+
+    @Test
+    public void test2() {
+
+        Double d1 = new Double(2.001);
+
+        List<Long> list2 = new ArrayList<>();
+
+        list2.add(1111L);
+        list2.add(2222L);
+        list2.add(3333L);
+        list2.add(4444L);
+        list2.add(5555L);
+        list2.add(6666L);
+
+
+        List<DoubleTsData> tsDataList = new ArrayList<>();
+
+        DoubleTsData doubleTsData1 = new DoubleTsData(1111L, (short) 1, 3.1);
+        DoubleTsData doubleTsData2 = new DoubleTsData(2222L, (short) 1, 3.2);
+        DoubleTsData doubleTsData3 = new DoubleTsData(3333L, (short) 1, 3.3);
+        DoubleTsData doubleTsData4 = new DoubleTsData(4444L, (short) 1, 3.4);
+        DoubleTsData doubleTsData5 = new DoubleTsData(5555L, (short) 1, 3.5);
+        DoubleTsData doubleTsData6 = new DoubleTsData(6666L, (short) 1, 3.6);
+        DoubleTsData doubleTsData7 = new DoubleTsData(7777L, (short) 1, 3.7);
+        DoubleTsData doubleTsData8 = new DoubleTsData(8888L, (short) 1, 3.8);
+        tsDataList.add(doubleTsData1);
+        tsDataList.add(doubleTsData2);
+        tsDataList.add(doubleTsData3);
+        tsDataList.add(doubleTsData4);
+        tsDataList.add(doubleTsData5);
+        tsDataList.add(doubleTsData6);
+        tsDataList.add(doubleTsData7);
+        tsDataList.add(doubleTsData8);
+
+        List<DoubleTsData> tsDataList2 = new ArrayList<>();
+        DoubleTsData doubleTsData11 = new DoubleTsData(1111L, (short) 1, 3.1);
+        DoubleTsData doubleTsData21 = new DoubleTsData(2222L, (short) 1, 3.2);
+        DoubleTsData doubleTsData31 = new DoubleTsData(3333L, (short) 1, 3.3);
+        DoubleTsData doubleTsData41 = new DoubleTsData(4444L, (short) 1, 3.4);
+        DoubleTsData doubleTsData51 = new DoubleTsData(5555L, (short) 1, 3.5);
+        DoubleTsData doubleTsData61 = new DoubleTsData(6666L, (short) 1, 3.6);
+        DoubleTsData doubleTsData71 = new DoubleTsData(7777L, (short) 1, 3.7);
+        DoubleTsData doubleTsData81 = new DoubleTsData(8888L, (short) 1, 3.8);
+        tsDataList2.add(doubleTsData11);
+        tsDataList2.add(doubleTsData21);
+        tsDataList2.add(doubleTsData31);
+        tsDataList2.add(doubleTsData41);
+        tsDataList2.add(doubleTsData51);
+        tsDataList2.add(doubleTsData61);
+        tsDataList2.add(doubleTsData71);
+        tsDataList2.add(doubleTsData81);
+
+
+        Map<String, List<DoubleTsData>> mp = new HashMap<>();
+
+        mp.put("a", tsDataList);
+        mp.put("b", tsDataList2);
+
+        Map<String, List<DoubleTsData>> resultMap = new HashMap<>();
+
+        for (Map.Entry<String, List<DoubleTsData>> entry :
+                mp.entrySet()) {
+
+            List<DoubleTsData> collect = tsDataList.stream().filter(s -> !list2.contains(s.getTs())).collect(Collectors.toList());
+
+            resultMap.put(entry.getKey(), collect);
+
+        }
+
+
+        List<DoubleTsData> collect2 = tsDataList.stream().filter(s -> !list2.contains(s.getTs())).collect(Collectors.toList());
+
+        System.out.println("---");
+
+
+    }
+
+    public void test3() throws NoSuchFieldException, ClassNotFoundException, InstantiationException, IllegalAccessException {
+
+        LcingTagNameData data = new LcingTagNameData();
+
+        Field field = data.getClass().getField("windturbineId");
+
+        Class<?> type = field.getType();
+
+        Class aClass = Class.forName(type.getName());
+
+        Object o = aClass.newInstance();
+
+
+    }
+
+    private static ThreadLocal<String> stringThreadLocal = new ThreadLocal<>();
+
+    static void print(String str) {
+        System.out.println(str + ":" + stringThreadLocal.get());
+        stringThreadLocal.remove();
+    }
+
+    public static void main(String[] args) throws InterruptedException {
+
+
+        new Thread(new Runnable() {
+            @Override
+            public void run() {
+                MyTest.stringThreadLocal.set("local_A");
+                print("A");
+                System.out.println("remove后:"+stringThreadLocal.get());
+            }
+        },"A").start();
+            Thread.sleep(1000);
+        new Thread(new Runnable() {
+            @Override
+            public void run() {
+                MyTest.stringThreadLocal.set("local_B");
+                print("B");
+                System.out.println("remove后:"+stringThreadLocal.get());
+            }
+        },"B").start();
+        Thread.sleep(1000);
+
+        String str1 = "通话";
+        String str2 = "重地";
+
+        System.out.println(str1.hashCode() + "====" + str2.hashCode());
+
+
+        LcingTagNameData lc1 = new LcingTagNameData();
+        LcingTagNameData lc2 = new LcingTagNameData();
+
+        lc1.setModel("UP82");
+        lc2.setModel("UP82");
+
+        System.out.println(lc1.hashCode() + "====" + lc2.hashCode());
+        System.out.println("equals===" + lc1.equals(lc2));
+        System.out.println("=" + (lc1 == lc2));
+
+
+    }
+
+
+}

+ 1 - 0
settings.gradle

@@ -16,4 +16,5 @@ include "alarm:windturbinenew"
 include "alarm:scadasnew"
 include "data-adapter"
 include 'risk-calc'
+include 'sample-kudu'
 

+ 11 - 6
warning-web/build.gradle

@@ -18,15 +18,16 @@ version = "2.0.1"
 apply plugin: "$bootGroup"
 apply plugin: "io.spring.dependency-management"
 
+tasks.named('test') {
+    useJUnitPlatform()
+}
 
 dependencies {
 
     implementation project(":common:utils")
-
-    //implementation fileTree(dir: "src/main/lib", include: "*.jar")
-    implementation ("mysql:mysql-connector-java:$mysqlConnectorVersion")
-    //implementation ("org.postgresql:postgresql:$postgresqlDriverVersion")
-
+   //implementation fileTree(dir: "src/main/lib", include: "*.jar")
+   //implementation ("mysql:mysql-connector-java:$mysqlConnectorVersion")
+    implementation ("org.postgresql:postgresql:$postgresqlDriverVersion")
 
     implementation("org.apache.commons:commons-lang3:$commonsLang3Version")
     implementation("$bootGroup:spring-boot-starter-web") {
@@ -35,6 +36,8 @@ dependencies {
     }
     implementation("$bootGroup:spring-boot-starter-undertow")
     implementation("$bootGroup:spring-boot-starter-websocket")
+    implementation("$bootGroup:spring-boot-starter-test")
+
     implementation("org.apache.logging.log4j:log4j-core:$log4jVersion")
     implementation("org.apache.logging.log4j:log4j-jul:$log4jVersion")
     implementation("org.apache.logging.log4j:log4j-api:$log4jVersion")
@@ -57,6 +60,8 @@ dependencies {
 
     implementation "org.springdoc:springdoc-openapi-ui:1.6.6"
 //    implementation "io.springfox:springfox-boot-starter:3.0.0"
-
+// https://mvnrepository.com/artifact/org.apache.spark/spark-core
+//    implementation group: 'org.apache.spark', name: 'spark-core_2.13', version: '3.2.2'
+//    implementation 'com.redislabs:spark-redis_2.11:2.4.2'
 }
 

+ 9 - 0
warning-web/src/main/java/com/gyee/wisdom/alarm/sharding/config/MyConfig.java

@@ -15,8 +15,17 @@ public class MyConfig {
    @Value("${rule_encryption:true}")
     private boolean ruleEncryption;
 
+
+    @Value("${rule_encryption_key:gyee-alarm123456}")
+    private String ruleEncryptionKey;
+
    public static boolean getRuleEncryption(){
        MyConfig bean = SpringContextUtil.getBean(MyConfig.class);
        return  bean.ruleEncryption;
    }
+
+    public static String getRuleEncryptionKey(){
+        MyConfig bean = SpringContextUtil.getBean(MyConfig.class);
+        return  bean.ruleEncryptionKey;
+    }
 }

+ 2 - 2
warning-web/src/main/java/com/gyee/wisdom/alarm/sharding/controller/AlarmUserController.java

@@ -46,7 +46,7 @@ public class AlarmUserController {
                 //单点登录
                 if (dbUser!=null) {
                     String token = "";
-                    token = TokenUtil.createJwtToken(user.getUserName());
+                    token = TokenUtil.createJwtToken(dbUser);
                     AlarmUser data = new AlarmUser();
                     data.setChineseName(dbUser.getChineseName());
                     data.setUserName(dbUser.getUserName());
@@ -64,7 +64,7 @@ public class AlarmUserController {
 
                 if (dataUser != null) {
                     String token = "";
-                    token = TokenUtil.createJwtToken(dataUser.getUserName());
+                    token = TokenUtil.createJwtToken(dataUser);
                     AlarmUser data = new AlarmUser();
                     data.setChineseName(dataUser.getChineseName());
                     data.setUserName(dataUser.getUserName());

+ 29 - 15
warning-web/src/main/java/com/gyee/wisdom/alarm/sharding/controller/Alertrule2Controller.java

@@ -1,8 +1,10 @@
 package com.gyee.wisdom.alarm.sharding.controller;
 
+import com.alibaba.fastjson.JSONObject;
 import com.baomidou.mybatisplus.core.metadata.IPage;
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import com.gyee.wisdom.alarm.sharding.config.AjaxResult;
+import com.gyee.wisdom.alarm.sharding.entity.AlarmUser;
 import com.gyee.wisdom.alarm.sharding.entity.Alertrule2;
 import com.gyee.wisdom.alarm.sharding.entity.DeviceMetrics;
 import com.gyee.wisdom.alarm.sharding.model.TreeNode;
@@ -11,6 +13,7 @@ import com.gyee.wisdom.alarm.sharding.util.ExcelUtil;
 import com.gyee.wisdom.alarm.sharding.util.TokenUtil;
 import com.gyee.wisdom.alarm.sharding.util.UserLoginToken;
 import com.gyee.wisdom.alarm.sharding.util.ResponseWrapper;
+import com.gyee.wisdom.common.utils.EncryptUtil;
 import io.jsonwebtoken.Claims;
 import io.swagger.v3.oas.annotations.Operation;
 import io.swagger.v3.oas.annotations.Parameter;
@@ -41,12 +44,14 @@ public class Alertrule2Controller {
     @Autowired
     private Alertrule2Service alertrule2Service;
 
+    @UserLoginToken
     @GetMapping(value = "/list")
     public List<Alertrule2> queryTree() {
         List<Alertrule2> alertrules = alertrule2Service.queryTree();
         return alertrules;
     }
 
+    @UserLoginToken
     @GetMapping(value = "/map")
     public List<Map<String, Alertrule2>> queryMap() {
         List<Map<String, Alertrule2>> alertrules = alertrule2Service.queryMap();
@@ -58,14 +63,15 @@ public class Alertrule2Controller {
     @PostMapping(value = "/save")
     @ResponseBody
     @UserLoginToken
-    public ResponseWrapper<Alertrule2> saveAlertrule2(HttpServletRequest request, @RequestBody Alertrule2 alertrule2) {
+    public ResponseWrapper<Alertrule2> saveAlertrule2(HttpServletRequest request, @RequestBody Alertrule2 alertrule2) throws Exception {
 
         String token=request.getHeader("token");
         Claims claims = TokenUtil.parseJWT(token);
         String userName=claims.get("jti").toString();
+        AlarmUser userData= JSONObject.parseObject(claims.getSubject(),AlarmUser.class);
         ResponseWrapper<Alertrule2> wrapper = dataCheck(alertrule2);
         if (wrapper.getSuccess()) {
-            int result = alertrule2Service.saveAndUpdateAlertrule2(alertrule2,userName);
+            int result = alertrule2Service.saveAndUpdateAlertrule2(alertrule2,userData);
             if (result <= 0) {
                 if(result==-999)
                 {
@@ -91,7 +97,7 @@ public class Alertrule2Controller {
 
     //@UserLoginToken
     @GetMapping(value = "/page")
-    public IPage<Alertrule2> queryByPage(
+    public IPage<Alertrule2> queryByPage(HttpServletRequest request,
             @RequestParam(value = "pagenum") Integer pageNum,
             @RequestParam(value = "pagesize") Integer pageSize,
             @RequestParam(value = "name", required = false) String name,
@@ -103,7 +109,12 @@ public class Alertrule2Controller {
             @RequestParam(value = "relatedparts",required = false) String relatedparts
     ) {
         Page<Alertrule2> page = new Page(pageNum, pageSize);
-        IPage<Alertrule2> pageResult = alertrule2Service.pageQueryAll(page, name,station,modelId,rank,category,enabled,relatedparts);
+//        String token=request.getHeader("token");
+//        Claims claims = TokenUtil.parseJWT(token);
+//        AlarmUser userData= JSONObject.parseObject(claims.getSubject(),AlarmUser.class);
+//        IPage<Alertrule2> pageResult = alertrule2Service.pageQueryAll(userData,page, name,station,modelId,rank,category,enabled,relatedparts);
+//
+          IPage<Alertrule2> pageResult = alertrule2Service.pageQueryAll2(page, name,station,modelId,rank,category,enabled,relatedparts);
 
         return pageResult;
     }
@@ -124,10 +135,12 @@ public class Alertrule2Controller {
         } else if (StringUtils.isBlank(alertrule.getRank())) {
             msg = "报警级别不能为空";
             result = false;
-        } else if (StringUtils.isBlank(alertrule.getEnabled()+"")) {
-            msg = "是否可用不能为空";
-            result = false;
-        } else if (StringUtils.isBlank(alertrule.getStation())) {
+        }
+//        else if (StringUtils.isBlank(alertrule.getEnabled()+"")) {
+//            msg = "是否可用不能为空";
+//            result = false;
+//        }
+        else if (StringUtils.isBlank(alertrule.getStation())) {
             msg = "风场不能为空";
             result = false;
         } else if (StringUtils.isBlank(alertrule.getCategory())) {
@@ -153,12 +166,11 @@ public class Alertrule2Controller {
     @PostMapping(value = "/save-batch")
     @ResponseBody
     @UserLoginToken
-    public ResponseWrapper<Alertrule2> saveAlertrule2Batch(HttpServletRequest request,@RequestBody List<Alertrule2> lst) {
+    public ResponseWrapper<Alertrule2> saveAlertrule2Batch(HttpServletRequest request,@RequestBody List<Alertrule2> lst) throws Exception {
 
         String token=request.getHeader("token");
         Claims claims = TokenUtil.parseJWT(token);
-        String userName=claims.get("jti").toString();
-
+        AlarmUser userData= JSONObject.parseObject(claims.getSubject(),AlarmUser.class);
         boolean allCheck = true;
         ResponseWrapper<Alertrule2> wrapper = null;
         for (Alertrule2 alertRule : lst) {
@@ -172,7 +184,7 @@ public class Alertrule2Controller {
         }
         if (allCheck) {
             for (Alertrule2 alertRule : lst) {
-                int result = alertrule2Service.saveAndUpdateAlertrule2(alertRule,userName);
+                int result = alertrule2Service.saveAndUpdateAlertrule2(alertRule,userData);
                 if (result <= 0) {
                     wrapper.setMsg(alertRule.getName() + ":" + "操作数据库失败");
                     wrapper.setSuccess(false);
@@ -195,7 +207,7 @@ public class Alertrule2Controller {
     public ResponseWrapper<Alertrule2> importAlertrule(@Parameter(description = "导入文件") @RequestParam("file") MultipartFile file, HttpServletRequest request) {
         String token=request.getHeader("token");
         Claims claims = TokenUtil.parseJWT(token);
-        String userName=claims.get("jti").toString();
+        AlarmUser userData= JSONObject.parseObject(claims.getSubject(),AlarmUser.class);
         ResponseWrapper<Alertrule2> wrapper = null;
         boolean allCheck = true;
         if (!file.isEmpty()) {
@@ -218,7 +230,7 @@ public class Alertrule2Controller {
                     alertrule2.setName(str[1]);
                     alertrule2.setCategory(str[2]);
                     alertrule2.setRank(str[3]);
-                    alertrule2.setEnabled(Integer.parseInt(str[4]));
+                    alertrule2.setEnabled(Boolean.parseBoolean(str[4]));
                     alertrule2.setStation(str[5]);
                     alertrule2.setModelId(str[6]);
                     alertrule2.setRelatedParts(str[7]);
@@ -237,7 +249,7 @@ public class Alertrule2Controller {
                 }
                 if (allCheck) {
                     for (Alertrule2 alertRule : bindingList) {
-                        int result = alertrule2Service.saveAndUpdateAlertrule2(alertRule, userName);
+                        int result = alertrule2Service.saveAndUpdateAlertrule2(alertRule, userData);
                         if (result <= 0) {
                             wrapper.setMsg(alertRule.getName() + ":" + "操作数据库失败");
                             wrapper.setSuccess(false);
@@ -250,6 +262,8 @@ public class Alertrule2Controller {
                 }
             } catch (IOException e) {
                 e.printStackTrace();
+            } catch (Exception e) {
+                e.printStackTrace();
             }
         }
         return wrapper;

+ 1 - 1
warning-web/src/main/java/com/gyee/wisdom/alarm/sharding/controller/DeviceController.java

@@ -145,7 +145,7 @@ public class DeviceController {
     public IPage<DeviceMetrics> queryByPage(
             @Parameter(name="pagenum",description = "当前页")  @RequestParam(value = "pagenum")Integer pageNum,
             @Parameter(name="pagesize",description = "分页大小")@RequestParam(value = "pagesize")Integer pageSize,
-            @Parameter(name="categorydata",description = "测点类型 AI-遥测 CI-计算 MI-遥调")  @RequestParam(value = "categorydata")String categorydata,
+            @Parameter(name="categorydata",description = "测点类型 AI-遥测 CI-计算 MI-遥调")  @RequestParam(value = "categorydata",required = false)String categorydata,
             @Parameter(name="keyword",description = "名称关键字")  @RequestParam(value = "keyword",required = false)String  keyword,
             @Parameter(name="model",description = "型号")  @RequestParam(value = "model",required = false)String  model,
             @Parameter(name="deviceId",description = "设备类型") @RequestParam(value = "deviceId", required = false) String deviceId,

+ 2 - 0
warning-web/src/main/java/com/gyee/wisdom/alarm/sharding/controller/InfoController.java

@@ -27,6 +27,7 @@ import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
+import java.util.stream.Collectors;
 
 /**
  * @descrition: 页面基本信息
@@ -102,6 +103,7 @@ public class InfoController {
     @ResponseBody
     public List<Windturbine> getWindturbineByStation(@Parameter(name = "stationId", description = "场站名称") @RequestParam(value = "stationId", required = false) String stationId) {
         List<Windturbine> lst = windturbineService.selectWindturbineByStationid(stationId);
+        lst = lst.stream().filter(s -> s.getWindpowerstationid().contains("_FDC")).collect(Collectors.toList());
         return lst;
     }
 

+ 68 - 9
warning-web/src/main/java/com/gyee/wisdom/alarm/sharding/controller/TestController.java

@@ -3,9 +3,12 @@ package com.gyee.wisdom.alarm.sharding.controller;
 import com.alibaba.fastjson.JSON;
 import com.alibaba.fastjson.JSONObject;
 import com.gyee.wisdom.alarm.sharding.entity.Windturbine;
+import com.gyee.wisdom.alarm.sharding.schedule.CreateTablesScheduled;
 import com.gyee.wisdom.alarm.sharding.service.AlarmReportService;
 import com.gyee.wisdom.alarm.sharding.service.AlarmSnapService;
+import com.gyee.wisdom.alarm.sharding.util.ResponseWrapper;
 import com.gyee.wisdom.alarm.sharding.util.SnowflakeGenerator;
+import com.gyee.wisdom.alarm.sharding.util.SpringContextUtil;
 import com.gyee.wisdom.alarm.sharding.util.StringUtil;
 import io.swagger.v3.oas.annotations.Operation;
 import io.swagger.v3.oas.annotations.Parameter;
@@ -65,10 +68,10 @@ public class TestController {
     @Operation(description = "根据字典类型获取字典集合")
     public JSONObject getSnowId() {
 
-        JSONObject obj=new JSONObject();
+        JSONObject obj = new JSONObject();
         obj.put("id", SnowflakeGenerator.generateId());
-        obj.put("name","wanghs");
-        obj.put("age","32");
+        obj.put("name", "wanghs");
+        obj.put("age", "32");
         return obj;
     }
 
@@ -116,16 +119,16 @@ public class TestController {
         System.out.println(b);
     }
 
-    public static boolean stringCompare(){
-        String code="wanghs";
-        char[] chr=code.toCharArray();
+    public static boolean stringCompare() {
+        String code = "wanghs";
+        char[] chr = code.toCharArray();
         for (int i = 0; i < chr.length; i++) {
 
-            char key=chr[i];
+            char key = chr[i];
 
-            for (int j = i+1; j < chr.length; j++) {
+            for (int j = i + 1; j < chr.length; j++) {
 
-                if(key==chr[j])
+                if (key == chr[j])
                     return false;
             }
 
@@ -133,4 +136,60 @@ public class TestController {
         }
         return true;
     }
+
+
+    @GetMapping("/addTable")
+    public String tableAdd(){
+        CreateTablesScheduled bean = SpringContextUtil.getBean(CreateTablesScheduled.class);
+        bean.doTask();
+        return "";
+
+    }
+
+    @GetMapping("/expection1/{vs}")
+    public ResponseWrapper testExpection1(@PathVariable("vs") Integer vs) {
+        if (vs == 20) {
+            vs=null;
+            boolean equals = vs.equals("123");
+
+
+            return ResponseWrapper.success("请求成功,null异常测试", equals);
+        }
+        if (vs == 10) {
+
+            int s = vs / 0;
+            return ResponseWrapper.success("请求成功,除0测试", s);
+        } else {
+            return ResponseWrapper.success(0);
+        }
+    }
+
+    @GetMapping("/expection2/{vs}")
+    public ResponseWrapper testExpection2(@PathVariable("vs") Integer vs) throws Throwable {
+
+        if(vs==0)
+            throw new Throwable("Throwable异常");
+
+        if(vs==3){
+            int s = vs / 0;
+            return ResponseWrapper.success("请求成功,除0测试");
+
+        }
+        return ResponseWrapper.success("请求成功");
+
+    }
+    @GetMapping("/system")
+    public String systemOutStack(){
+        Integer i=null;
+
+        try {
+            System.out.println(i.byteValue());
+        }catch (Exception e){
+            log.error("==cause"+e.getCause());
+            log.error("--stack"+e.getStackTrace());
+            log.error("123",e);
+        }
+
+        return "123";
+    }
 }

+ 4 - 0
warning-web/src/main/java/com/gyee/wisdom/alarm/sharding/entity/AlarmUser.java

@@ -34,6 +34,10 @@ public class AlarmUser implements Serializable {
     private int enabled;
     @TableField("IDENTITY")
     private String identity;
+
+    //0,1,2 0为最低权限仅可以查看为0的规则,1为普通权限可以查看为0,1的规则,2为超级权限可以查看所有规则
+    @TableField("RULELEVEL")
+    private int ruleLevel;
     @TableField(exist = false)
     private  String mark;
 }

+ 22 - 22
warning-web/src/main/java/com/gyee/wisdom/alarm/sharding/entity/Alertrule2.java

@@ -24,11 +24,11 @@ public class Alertrule2 implements Serializable {
     @ChineseDes("名称")
     @TableField("Name")
     private String name;
-    @JSONField(serialize=false,deserialize = false) //不序列化
+    @JSONField(serialize = false, deserialize = false) //不序列化
     @ChineseDes("规则描述")
     @TableField("description")
     private String description;
-    @JSONField(serialize=false,deserialize = false)//不序列化
+    @JSONField(serialize = false, deserialize = false)//不序列化
     @ChineseDes("表达式")
     @TableField("expression")
     private String expression;
@@ -40,7 +40,7 @@ public class Alertrule2 implements Serializable {
     private String rank;
     @ChineseDes("是否启用")
     @TableField("enabled")
-    private int enabled;
+    private boolean enabled;
     @ChineseDes("风机类型")
     @TableField("modelId")
     private String modelId;
@@ -79,7 +79,12 @@ public class Alertrule2 implements Serializable {
     @ChineseDes("操作时间")
     @TableField("createtime")
     private Date createtime;//操作时间
+    @ChineseDes("展示等级,低等级不展示规则明文")
+    @TableField("RULELEVEL")
+    private Integer ruleLevel;
+
     //前端显示字段 防止报警规则泄漏
+    @JSONField(serialize = false, deserialize = false)//不序列化
     @TableField(exist = false)
     @Setter(AccessLevel.NONE)
     @Getter(AccessLevel.NONE)
@@ -90,32 +95,27 @@ public class Alertrule2 implements Serializable {
     @Getter(AccessLevel.NONE)
     private String expressionShow;
 
+    @TableField(exist = false)
     private WindPowerStation windPowerStation;
+    @TableField(exist = false)
     private Datadictionary datadictionary;
 
-    public  String getDescriptionShow(){
-        boolean ruleEncryption = MyConfig.getRuleEncryption();
-        if(ruleEncryption&&"1".equals(this.range))
-            return "***********";
-        else
-            return this.description;
-
+    public String getDescriptionShow() {
+        return this.descriptionShow;
     }
-    public String getExpressionShow(){
-        boolean ruleEncryption = MyConfig.getRuleEncryption();
-        if(ruleEncryption&&"1".equals(this.range))
-            return "***********";
-        else
-            return this.expression;
+
+    public String getExpressionShow() {
+        return this.expressionShow;
     }
 
-    public void setDescriptionShow(String descriptionShow){
-        this.description=descriptionShow;
-        this.descriptionShow=descriptionShow;
+    public void setDescriptionShow(String descriptionShow) {
+        this.description = descriptionShow;
+        this.descriptionShow = descriptionShow;
     }
 
-    public void setExpressionShow(String expression){
-        this.expression=expression;
-        this.expressionShow=expression;
+    public void setExpressionShow(String expression) {
+        this.expression = expression;
+        this.expressionShow = expression;
     }
+
 }

+ 1 - 1
warning-web/src/main/java/com/gyee/wisdom/alarm/sharding/entity/WindTurbineTestingPointAi.java

@@ -7,7 +7,7 @@ import lombok.Data;
 import java.io.Serializable;
 
 @Data
-@TableName("WINDTURBINETESTINGPOINTAI")
+@TableName("WINDTURBINETESTINGPOINTAI2")
 public class WindTurbineTestingPointAi implements Serializable {
     private static final long serialVersionUID = -7009408032434108640L;
     @TableId("ID")

+ 2 - 0
warning-web/src/main/java/com/gyee/wisdom/alarm/sharding/entity/WindTurbineTestingPointDi.java

@@ -2,11 +2,13 @@ package com.gyee.wisdom.alarm.sharding.entity;
 
 import com.baomidou.mybatisplus.annotation.TableField;
 import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
 import lombok.Data;
 
 import java.io.Serializable;
 
 @Data
+@TableName("WINDTURBINETESTINGPOINTDI2")
 public class WindTurbineTestingPointDi implements Serializable {
     private static final long serialVersionUID = -7009408032434108640L;
     @TableId("ID")

+ 88 - 0
warning-web/src/main/java/com/gyee/wisdom/alarm/sharding/exception/GloabalExceptionHandler.java

@@ -0,0 +1,88 @@
+package com.gyee.wisdom.alarm.sharding.exception;
+
+import com.gyee.wisdom.alarm.sharding.util.ResponseWrapper;
+import org.springframework.web.bind.MethodArgumentNotValidException;
+import org.springframework.web.bind.annotation.ControllerAdvice;
+import org.springframework.web.bind.annotation.ExceptionHandler;
+import org.springframework.web.bind.annotation.ResponseBody;
+
+import java.util.Map;
+
+/**
+ * @description:
+ * @auther: Wanghs
+ * @date: 2022-10-31
+ */
+@ControllerAdvice(basePackages = "com.gyee.wisdom.alarm.sharding.controller")
+public class GloabalExceptionHandler {
+
+
+
+//    ArithmeticException——由于除数为0引起的异常;
+//    ArrayStoreException——由于数组存储空间不够引起的异常;
+//    ClassCastException—一当把一个对象归为某个类,但实际上此对象并不是由这个类 创建的,也不是其子类创建的,则会引起异常;
+//    IllegalMonitorStateException——监控器状态出错引起的异常;
+//    NegativeArraySizeException—一数组长度是负数,则产生异常;
+//    NullPointerException—一程序试图访问一个空的数组中的元素或访问空的对象中的 方法或变量时产生异常;
+//    OutofMemoryException——用new语句创建对象时,如系统无法为其分配内存空 间则产生异常;
+//    SecurityException——由于访问了不应访问的指针,使安全性出问题而引起异常;
+//    IndexOutOfBoundsExcention——由于数组下标越界或字符串访问越界引起异常;
+//    IOException——由于文件未找到、未打开或者I/O操作不能进行而引起异常;
+//    ClassNotFoundException——未找到指定名字的类或接口引起异常;
+//    CloneNotSupportedException——一程序中的一个对象引用Object类的clone方法,但 此对象并没有连接Cloneable接口,从而引起异常;
+//    InterruptedException—一当一个线程处于等待状态时,另一个线程中断此线程,从 而引起异常;
+//    NoSuchMethodException一所调用的方法未找到,引起异常;
+//    Illega1AccessExcePtion—一试图访问一个非public方法;
+//    StringIndexOutOfBoundsException——访问字符串序号越界,引起异常;
+//    ArrayIdexOutOfBoundsException—一访问数组元素下标越界,引起异常;
+//    NumberFormatException——字符的UTF代码数据格式有错引起异常;
+//    IllegalThreadException—一线程调用某个方法而所处状态不适当,引起异常;
+//    FileNotFoundException——未找到指定文件引起异常;
+//    EOFException——未完成输入操作即遇文件结束引起异常。
+
+
+
+    //jsr303校验错误异常
+    @ExceptionHandler(value = MethodArgumentNotValidException.class)
+    @ResponseBody
+    public ResponseWrapper handleValidException(MethodArgumentNotValidException e) {
+
+        return ResponseWrapper.error("MethodArgumentNotValidException异常");
+
+    }
+
+
+
+    @ExceptionHandler(value = Throwable.class)
+    @ResponseBody
+    public ResponseWrapper handleValidException(Throwable throwable) {
+        ResponseWrapper data = ResponseWrapper.error("Throwable异常");
+        data.setData(throwable.getStackTrace());
+        return data;
+    }
+
+    @ExceptionHandler(value = ArithmeticException.class)
+    @ResponseBody
+    public ResponseWrapper handleArithmeticException(ArithmeticException exception) {
+        ResponseWrapper data = ResponseWrapper.error("ArithmeticException"+exception.getCause());
+        data.setData(exception.getStackTrace());
+        return data;
+    }
+
+    @ExceptionHandler(value = NullPointerException.class)
+    @ResponseBody
+    public ResponseWrapper handleNullPointerException(NullPointerException exception) {
+        ResponseWrapper data = ResponseWrapper.error("NullPointerException"+exception.getCause());
+        data.setData(exception.getStackTrace());
+        return data;
+    }
+
+    @ExceptionHandler(value = Exception.class)
+    @ResponseBody
+    public ResponseWrapper handleException(Exception exception) {
+        ResponseWrapper data = ResponseWrapper.error("Exception"+exception.getCause());
+        data.setData(exception.getStackTrace());
+        return data;
+    }
+
+}

+ 6 - 5
warning-web/src/main/java/com/gyee/wisdom/alarm/sharding/filter/LoginInterceptor.java

@@ -48,6 +48,7 @@ public class LoginInterceptor implements HandlerInterceptor {
     @Override
     public boolean preHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object object) throws Exception {
         String headerToken = httpServletRequest.getHeader("token");// 从 http 请求头中取出 token
+        httpServletResponse.setHeader("Content-Type", "application/json;charset=UTF-8");
         ServletOutputStream resultWriter = httpServletResponse.getOutputStream();
         // 如果不是映射到方法直接通过
         if (!(object instanceof HandlerMethod)) {
@@ -68,7 +69,7 @@ public class LoginInterceptor implements HandlerInterceptor {
             if (userLoginToken.required()) {
                 // 执行认证
                 if (headerToken == null) {
-                    ResponseWrapper wrapper=ResponseWrapper.error("请登陆!",521);
+                    ResponseWrapper wrapper = ResponseWrapper.error("请登陆!", 521);
                     resultWriter.write(JSON.toJSONString(wrapper).getBytes());
                     resultWriter.flush();
                     resultWriter.close();
@@ -86,7 +87,7 @@ public class LoginInterceptor implements HandlerInterceptor {
 
                     //如果用户名不存在,则说明token错误
                     if (null == myTokenUser) {
-                        ResponseWrapper wrapper=ResponseWrapper.error("身份验证错误,请重新登陆!",521);
+                        ResponseWrapper wrapper = ResponseWrapper.error("身份验证错误,请重新登陆!", 521);
                         resultWriter.write(JSON.toJSONString(wrapper).getBytes());
                         resultWriter.flush();
                         resultWriter.close();
@@ -97,8 +98,8 @@ public class LoginInterceptor implements HandlerInterceptor {
                     Date tokenDate = claims.getExpiration();
                     int overTime = (int) (new Date().getTime() - tokenDate.getTime()) / 1000;
                     //过期时间为一个小时
-                    if (overTime > 60*60  ) {
-                        ResponseWrapper wrapper=ResponseWrapper.error("身份验证过期,请重新登陆!",521);
+                    if (overTime > 60 * 60) {
+                        ResponseWrapper wrapper = ResponseWrapper.error("身份验证过期,请重新登陆!", 521);
                         resultWriter.write(JSON.toJSONString(wrapper).getBytes());
                         resultWriter.flush();
                         resultWriter.close();
@@ -106,7 +107,7 @@ public class LoginInterceptor implements HandlerInterceptor {
                     }
 
                 } catch (Exception e) {
-                    ResponseWrapper wrapper=ResponseWrapper.error("身份验证错误,请重新登陆!",521);
+                    ResponseWrapper wrapper = ResponseWrapper.error("身份验证错误,请重新登陆!", 521);
                     resultWriter.write(JSON.toJSONString(wrapper).getBytes());
                     resultWriter.flush();
                     resultWriter.close();

+ 18 - 17
warning-web/src/main/java/com/gyee/wisdom/alarm/sharding/schedule/CreateTablesScheduled.java

@@ -16,28 +16,29 @@ public class CreateTablesScheduled {
     String stationname;
     @Value("${tablespace}")
     String tablespace;
+
     //秒 分 时 日 月 周
-    /*@Scheduled(cron="0 34 11 * * 5")*/
-    public void doTask(){
+   // @Scheduled(cron = "0 0 02 * * 5")
+    public void doTask() {
         Calendar instance = Calendar.getInstance();
         //查看当前时间的下月是否有表,没有就创建
-        //instance.add(Calendar.MONTH,1);
-        String yearmonth=null;
-        int year=instance.get(Calendar.YEAR);
-        int month=instance.get(Calendar.MONTH)+1;
-        if(month<10){
-            yearmonth=year+"0"+month;
-        }else {
-            yearmonth=""+year+month;
+        instance.add(Calendar.MONTH,1);
+        String yearmonth = null;
+        int year = instance.get(Calendar.YEAR);
+        int month = instance.get(Calendar.MONTH) + 1;
+        if (month < 10) {
+            yearmonth = year + "0" + month;
+        } else {
+            yearmonth = "" + year + month;
         }
-        String[] stationnamelist=stationname.split(",");
+        String[] stationnamelist = stationname.split(",");
         //tablespace表空间
-        for (String s:stationnamelist) {
-            if(alarmHisotryMapper.isHasTable(s,yearmonth)==0){//表是否存在
-                alarmHisotryMapper.timedCreatTable(s,yearmonth,tablespace);
-                alarmHisotryMapper.timedAlterTable(s,yearmonth,tablespace);
-                alarmHisotryMapper.timedCreatAlerttimeIndex(s,yearmonth,tablespace);
-                alarmHisotryMapper.timedCreatSnapidIndex(s,yearmonth,tablespace);
+        for (String s : stationnamelist) {
+            if (alarmHisotryMapper.isHasTable(s, yearmonth) == 0) {//表是否存在
+                alarmHisotryMapper.timedCreatTable(s, yearmonth, tablespace);
+              //  alarmHisotryMapper.timedAlterTable(s, yearmonth, tablespace);
+                alarmHisotryMapper.timedCreatAlerttimeIndex(s, yearmonth, tablespace);
+                alarmHisotryMapper.timedCreatSnapidIndex(s, yearmonth, tablespace);
                 System.out.println(s);
             }
         }

+ 79 - 35
warning-web/src/main/java/com/gyee/wisdom/alarm/sharding/service/Alertrule2Service.java

@@ -4,6 +4,7 @@ import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
 import com.baomidou.mybatisplus.core.metadata.IPage;
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.gyee.wisdom.alarm.sharding.config.MyConfig;
 import com.gyee.wisdom.alarm.sharding.controller.AlertRuleEventLogController;
 import com.gyee.wisdom.alarm.sharding.entity.*;
 import com.gyee.wisdom.alarm.sharding.logtool.LogService;
@@ -14,9 +15,11 @@ import com.gyee.wisdom.alarm.sharding.model.AlarmHome;
 import com.gyee.wisdom.alarm.sharding.model.Alertrule2Example;
 import com.gyee.wisdom.alarm.sharding.model.TreeNode;
 import com.gyee.wisdom.alarm.sharding.util.DateUtils;
+import com.gyee.wisdom.alarm.sharding.util.SpringContextUtil;
 import com.gyee.wisdom.alarm.sharding.util.StringUtil;
 import com.gyee.wisdom.alarm.sharding.util.UUIDUtil;
 
+import com.gyee.wisdom.common.utils.EncryptUtil;
 import lombok.extern.slf4j.Slf4j;
 import org.apache.commons.lang3.StringUtils;
 import org.apache.logging.log4j.LogManager;
@@ -45,21 +48,20 @@ public class Alertrule2Service extends ServiceImpl<Alertrule2Mapper, Alertrule2>
     private RuleUpdateEventService eventService;
 
 
-
-    public int saveAndUpdateAlertrule2(Alertrule2 alertrule2,String userName) {
+    public int saveAndUpdateAlertrule2(Alertrule2 alertrule2, AlarmUser userData) throws Exception {
 
         int result = 0;
-        Alertrule2 oldRule2=null;
+        Alertrule2 oldRule2 = null;
         if (StringUtils.isBlank(alertrule2.getId())) {
             //生成id,生成规则为HD+自增数
 //            String station = StringUtils.substringBefore(alertrule2.getStation(), "_");
             Integer maxEdnaValue = alertrule2Mapper.getMaxEdnaValue();
-           int max = maxEdnaValue + 1;
-            String first="";
+            int max = maxEdnaValue + 1;
+            String first = "";
             String[] s = alertrule2.getStation().split("_");
-            if(s.length>1)
-                first=s[0];
-            String newId = first+"_"+ max;
+            if (s.length > 1)
+                first = s[0];
+            String newId = first + "_" + max;
             //验证生成的id是否已存在
             List<Alertrule2> selectList = alertrule2Mapper.getById(newId);
             if (selectList.size() > 0) {
@@ -75,6 +77,14 @@ public class Alertrule2Service extends ServiceImpl<Alertrule2Mapper, Alertrule2>
 
                 alertrule2.setEdnaValue(nextEdnaValue);
                 alertrule2.setCreatetime(DateUtils.getNowDate());
+
+                //针对规则表达式和规则进行加密
+              if(StringUtils.isNotBlank(  MyConfig.getRuleEncryptionKey())){
+                  alertrule2.setExpression(EncryptUtil.encryptAES(alertrule2.getExpression(),MyConfig.getRuleEncryptionKey()));
+                  alertrule2.setDescription(EncryptUtil.encryptAES(alertrule2.getDescription(),MyConfig.getRuleEncryptionKey()));
+                  alertrule2.setRuleLevel(userData.getRuleLevel());
+              }
+
                 result = alertrule2Mapper.insertAlerture2(alertrule2);
                 if (result > 0) {
                     logService.alertRuleAddLog(alertrule2, alertrule2.getUserName());
@@ -82,7 +92,7 @@ public class Alertrule2Service extends ServiceImpl<Alertrule2Mapper, Alertrule2>
             }
 
         } else {
-             oldRule2 = alertrule2Mapper.selectByAlertrule2Id(alertrule2.getId());
+            oldRule2 = alertrule2Mapper.selectByAlertrule2Id(alertrule2.getId());
             if (oldRule2 != null) {
                 result = alertrule2Mapper.updateByAlertrule2Id(alertrule2);
                 if (result > 0) {
@@ -90,8 +100,8 @@ public class Alertrule2Service extends ServiceImpl<Alertrule2Mapper, Alertrule2>
                 }
             }
         }
-        if(result>0) {
-            int i = eventService.saveEventAlertRule(alertrule2, oldRule2,userName);
+        if (result > 0) {
+            int i = eventService.saveEventAlertRule(alertrule2, oldRule2, userData.getUserName());
         }
         return result;
     }
@@ -100,8 +110,43 @@ public class Alertrule2Service extends ServiceImpl<Alertrule2Mapper, Alertrule2>
         return alertrule2Mapper.deleteById(alertrule2.getId());
     }
 
-    public IPage<Alertrule2> pageQueryAll(Page page, String name,String station,String modelId,String rank,String category,String enabled, String relatedparts) {
-        return alertrule2Mapper.pageQueryAll(page, name,station,modelId,rank,category,enabled,relatedparts);
+    public IPage<Alertrule2> pageQueryAll(AlarmUser user, Page page, String name, String station, String modelId, String rank, String category, String enabled, String relatedparts) {
+        IPage<Alertrule2> alertrule2IPage = alertrule2Mapper.pageQueryAll(page, name, station, modelId, rank, category, enabled, relatedparts);
+            alertrule2IPage.getRecords().forEach(s -> {
+                //如果规则ruleLevel字段不为空,代表数据是加密了的
+                if(s.getRuleLevel()!=null){
+                    if ( user.getRuleLevel()>=s.getRuleLevel()) {
+                        try {
+                            String expression = EncryptUtil.decryptAES(s.getExpression(), MyConfig.getRuleEncryptionKey());
+                            s.setExpression(expression);
+                            s.setExpressionShow(expression);
+
+                            String description = EncryptUtil.decryptAES(s.getDescription(), MyConfig.getRuleEncryptionKey());
+                            s.setDescription(description);
+                            s.setDescriptionShow(description);
+                        } catch (Exception e) {
+                            e.printStackTrace();
+                        }
+                    }else{
+                        s.setExpression("***********");
+                        s.setExpressionShow("***********");
+                        s.setDescription("***********");
+                        s.setDescriptionShow("***********");
+                    }
+                }else{
+                    s.setDescriptionShow(s.getDescription());
+                    s.setExpressionShow(s.getExpression());
+                }
+
+            });
+
+        return alertrule2IPage;
+    }
+
+    public IPage<Alertrule2> pageQueryAll2(Page page, String name, String station, String modelId, String rank, String category, String enabled, String relatedparts) {
+        IPage<Alertrule2> alertrule2IPage = alertrule2Mapper.pageQueryAll(page, name, station, modelId, rank, category, enabled, relatedparts);
+
+        return alertrule2IPage;
     }
 
     //根据场站风机型号生成最新自定义报警规则ID
@@ -128,30 +173,29 @@ public class Alertrule2Service extends ServiceImpl<Alertrule2Mapper, Alertrule2>
     }
 
 
-
     public List<Alertrule2> queryTree() {
         List<Alertrule2> dsList = alertrule2Mapper.queryTree();
         return dsList;
     }
 
-//首页风机部件查询
-    public  Map<String,Integer> queryList(String station, String modelId) {
-        Map<String,Integer> map2 = new HashMap<>();
-        map2.put("CLX",0);
-        map2.put("YP",0);
-        map2.put("YY",0);
-        map2.put("BJXT",0);
-        map2.put("PHXT",0);
-        map2.put("BPXT",0);
-        map2.put("CFXT",0);
-        map2.put("ZZ",0);
-        map2.put("FDJ",0);
-        map2.put("QT",0);
-
-        List<Alertrule2> dslist = alertrule2Mapper.getAllByStationIdAndModelId2(station,modelId);
-        map2.put("SUM",dslist.size());
-        for(Alertrule2 ar : dslist) {
-            int cnt= 0;
+    //首页风机部件查询
+    public Map<String, Integer> queryList(String station, String modelId) {
+        Map<String, Integer> map2 = new HashMap<>();
+        map2.put("CLX", 0);
+        map2.put("YP", 0);
+        map2.put("YY", 0);
+        map2.put("BJXT", 0);
+        map2.put("PHXT", 0);
+        map2.put("BPXT", 0);
+        map2.put("CFXT", 0);
+        map2.put("ZZ", 0);
+        map2.put("FDJ", 0);
+        map2.put("QT", 0);
+
+        List<Alertrule2> dslist = alertrule2Mapper.getAllByStationIdAndModelId2(station, modelId);
+        map2.put("SUM", dslist.size());
+        for (Alertrule2 ar : dslist) {
+            int cnt = 0;
             switch (ar.getRelatedParts()) {
                 case "CLX":
                     cnt = map2.get("CLX").intValue();
@@ -175,7 +219,7 @@ public class Alertrule2Service extends ServiceImpl<Alertrule2Mapper, Alertrule2>
                     break;
                 case "BPXT":
                     cnt = map2.get("BPXT").intValue();
-                    map2.put("BPXT",++cnt);
+                    map2.put("BPXT", ++cnt);
                     break;
                 case "CFXT":
                     cnt = map2.get("CFXT").intValue();
@@ -187,7 +231,7 @@ public class Alertrule2Service extends ServiceImpl<Alertrule2Mapper, Alertrule2>
                     break;
                 case "FDJ":
                     cnt = map2.get("FDJ").intValue();
-                    map2.put("FDJ",++cnt);
+                    map2.put("FDJ", ++cnt);
                     break;
                 default:
                     cnt = map2.get("QT").intValue();
@@ -219,7 +263,7 @@ public class Alertrule2Service extends ServiceImpl<Alertrule2Mapper, Alertrule2>
         return alertrule2Map;
     }
 
-    public List<String> getUniformCodeByNameAndStation(String name, String station, String modelid){
+    public List<String> getUniformCodeByNameAndStation(String name, String station, String modelid) {
         Alertrule2Example example = new Alertrule2Example();
         example.createCriteria().andNameEqualTo(name)
                 .andStationEqualTo(station)

+ 14 - 6
warning-web/src/main/java/com/gyee/wisdom/alarm/sharding/util/TokenUtil.java

@@ -2,6 +2,9 @@ package com.gyee.wisdom.alarm.sharding.util;
 
 
 
+import com.alibaba.fastjson.JSON;
+import com.alibaba.fastjson.JSONObject;
+import com.gyee.wisdom.alarm.sharding.entity.AlarmUser;
 import io.jsonwebtoken.Claims;
 import io.jsonwebtoken.JwtBuilder;
 import io.jsonwebtoken.Jwts;
@@ -25,21 +28,21 @@ public class TokenUtil {
 
     /**
      * 生成token
-     * @param username
+     * @param user
      * @return
      */
-    public static String createJwtToken(String username){
+    public static String createJwtToken(AlarmUser user){
         long ttlMillis=3600000;//1个小时后过期
-        return createJwtToken(username,ttlMillis);
+        return createJwtToken(user,ttlMillis);
     }
 
     /**
      * 生成token
-     * @param username 用户名
+     * @param user 用户名
      * @param ttlMillis 签发时间(有效时间,过期会报错)
      * @return token string
      */
-    public static String createJwtToken(String username,long ttlMillis){
+    public static String createJwtToken(AlarmUser user,long ttlMillis){
         //签名算法,将token进行签名
         SignatureAlgorithm signatureAlgorithm=SignatureAlgorithm.HS256;
         //生成签发时间
@@ -49,7 +52,12 @@ public class TokenUtil {
         byte[] apiKeySecretBytes= DatatypeConverter.parseBase64Binary(SECRET);
         Key signingKey=new SecretKeySpec(apiKeySecretBytes,signatureAlgorithm.getJcaName());
         //创建token
-        JwtBuilder builder= Jwts.builder().setId(username)
+        JSONObject jsonObject=new JSONObject();
+        jsonObject.put("userName",user.getUserName());
+        jsonObject.put("chineseName",user.getChineseName());
+        jsonObject.put("identity",user.getIdentity());
+        jsonObject.put("ruleLevel",user.getRuleLevel());
+        JwtBuilder builder= Jwts.builder().setId(user.getUserName()).setSubject(jsonObject.toJSONString())
                 .setIssuedAt(now)
                 .signWith(signatureAlgorithm,signingKey);
         //添加过期时间

+ 0 - 0
warning-web/src/main/resources/application.yaml


Некоторые файлы не были показаны из-за большого количества измененных файлов