by su 3 years ago
parent
commit
1aaaa8f844
52 changed files with 5066 additions and 14 deletions
  1. 61 2
      4dkankan-common-utils/pom.xml
  2. 71 0
      4dkankan-common-utils/src/main/java/com/fdkankan/common/constant/AppConstant.java
  3. 27 0
      4dkankan-common-utils/src/main/java/com/fdkankan/common/constant/BuildStatus.java
  4. 41 0
      4dkankan-common-utils/src/main/java/com/fdkankan/common/constant/Constant.java
  5. 9 0
      4dkankan-common-utils/src/main/java/com/fdkankan/common/constant/ConstantRegex.java
  6. 25 0
      4dkankan-common-utils/src/main/java/com/fdkankan/common/constant/DownloadStatus.java
  7. 18 0
      4dkankan-common-utils/src/main/java/com/fdkankan/common/constant/LoginType.java
  8. 17 0
      4dkankan-common-utils/src/main/java/com/fdkankan/common/constant/OrderConstant.java
  9. 26 0
      4dkankan-common-utils/src/main/java/com/fdkankan/common/constant/PayStatus.java
  10. 24 0
      4dkankan-common-utils/src/main/java/com/fdkankan/common/constant/RecStatus.java
  11. 111 0
      4dkankan-common-utils/src/main/java/com/fdkankan/common/constant/SceneConstant.java
  12. 25 0
      4dkankan-common-utils/src/main/java/com/fdkankan/common/constant/SceneEditType.java
  13. 26 0
      4dkankan-common-utils/src/main/java/com/fdkankan/common/constant/SceneStatus.java
  14. 29 0
      4dkankan-common-utils/src/main/java/com/fdkankan/common/constant/SceneType.java
  15. 24 0
      4dkankan-common-utils/src/main/java/com/fdkankan/common/constant/TbStatus.java
  16. 25 0
      4dkankan-common-utils/src/main/java/com/fdkankan/common/constant/UploadStatus.java
  17. 26 0
      4dkankan-common-utils/src/main/java/com/fdkankan/common/constant/ZipStatus.java
  18. 602 0
      4dkankan-common-utils/src/main/java/com/fdkankan/common/proto/format/SmileFormat.java
  19. 45 0
      4dkankan-common-utils/src/main/java/com/fdkankan/common/util/AesUtil.java
  20. 1 1
      4dkankan-common-utils/src/main/java/com/fdkankan/common/utils/Base64Converter.java
  21. 591 0
      4dkankan-common-utils/src/main/java/com/fdkankan/common/util/ComputerUtil.java
  22. 1 1
      4dkankan-common-utils/src/main/java/com/fdkankan/common/utils/ConstantCmd.java
  23. 219 0
      4dkankan-common-utils/src/main/java/com/fdkankan/common/util/ConvertCommonUtils.java
  24. 219 0
      4dkankan-common-utils/src/main/java/com/fdkankan/common/util/ConvertUtils.java
  25. 1 1
      4dkankan-common-utils/src/main/java/com/fdkankan/common/utils/CreateObjUtil.java
  26. 1 1
      4dkankan-common-utils/src/main/java/com/fdkankan/common/utils/DataUtils.java
  27. 46 0
      4dkankan-common-utils/src/main/java/com/fdkankan/common/util/DateEditor.java
  28. 33 0
      4dkankan-common-utils/src/main/java/com/fdkankan/common/util/DateExtUtil.java
  29. 411 0
      4dkankan-common-utils/src/main/java/com/fdkankan/common/util/DateUtil.java
  30. 133 0
      4dkankan-common-utils/src/main/java/com/fdkankan/common/util/FileMd5Util.java
  31. 141 0
      4dkankan-common-utils/src/main/java/com/fdkankan/common/util/FileSizeUtil.java
  32. 134 0
      4dkankan-common-utils/src/main/java/com/fdkankan/common/util/FileUpload.java
  33. 1 1
      4dkankan-common-utils/src/main/java/com/fdkankan/common/utils/FileUtil.java
  34. 1 1
      4dkankan-common-utils/src/main/java/com/fdkankan/common/utils/FileUtils.java
  35. 1 1
      4dkankan-common-utils/src/main/java/com/fdkankan/common/utils/JwtUtil.java
  36. 70 0
      4dkankan-common-utils/src/main/java/com/fdkankan/common/util/LogoConfig.java
  37. 107 0
      4dkankan-common-utils/src/main/java/com/fdkankan/common/util/MatrixToImageWriterUtil.java
  38. 86 0
      4dkankan-common-utils/src/main/java/com/fdkankan/common/util/NumberUtils.java
  39. 314 0
      4dkankan-common-utils/src/main/java/com/fdkankan/common/util/OkHttpUtils.java
  40. 190 0
      4dkankan-common-utils/src/main/java/com/fdkankan/common/util/PasswordUtils.java
  41. 102 0
      4dkankan-common-utils/src/main/java/com/fdkankan/common/util/PatternUtils.java
  42. 465 0
      4dkankan-common-utils/src/main/java/com/fdkankan/common/util/RSAEncrypt.java
  43. 49 0
      4dkankan-common-utils/src/main/java/com/fdkankan/common/util/RandomUtil.java
  44. 206 0
      4dkankan-common-utils/src/main/java/com/fdkankan/common/util/RubberSheetingUtil.java
  45. 1 1
      4dkankan-common-utils/src/main/java/com/fdkankan/common/utils/SHAUtils.java
  46. 32 0
      4dkankan-common-utils/src/main/java/com/fdkankan/common/util/SecurityUtil.java
  47. 135 0
      4dkankan-common-utils/src/main/java/com/fdkankan/common/util/SnowflakeIdGenerator.java
  48. 12 0
      4dkankan-common-utils/src/main/java/com/fdkankan/common/util/StrExtUtil.java
  49. 1 1
      4dkankan-common-utils/src/main/java/com/fdkankan/common/utils/StreamGobbler.java
  50. 112 0
      4dkankan-common-utils/src/main/java/com/fdkankan/common/util/WeiXinUtils.java
  51. 1 3
      4dkankan-utils-redis/pom.xml
  52. 17 0
      pom.xml

+ 61 - 2
4dkankan-common-utils/pom.xml

@@ -62,10 +62,22 @@
             <artifactId>fastjson</artifactId>
         </dependency>
 
+<!--        <dependency>-->
+<!--            <groupId>org.springframework</groupId>-->
+<!--            <artifactId>spring-context</artifactId>-->
+<!--            <version>5.2.15.RELEASE</version>-->
+<!--        </dependency>-->
+
+<!--        <dependency>-->
+<!--            <groupId>org.springframework</groupId>-->
+<!--            <artifactId>spring-web</artifactId>-->
+<!--            <version>5.2.15.RELEASE</version>-->
+<!--        </dependency>-->
+
         <dependency>
             <groupId>org.springframework</groupId>
-            <artifactId>spring-context</artifactId>
-            <version>5.2.15.RELEASE</version>
+            <artifactId>spring-webmvc</artifactId>
+            <version>5.3.13</version>
         </dependency>
 
         <dependency>
@@ -80,6 +92,53 @@
             <version>0.6.0</version>
         </dependency>
 
+        <dependency>
+            <groupId>org.codehaus.jackson</groupId>
+            <artifactId>jackson-smile</artifactId>
+            <version>1.9.12</version>
+        </dependency>
+
+        <dependency>
+            <groupId>com.aliyun</groupId>
+            <artifactId>aliyun-java-sdk-core</artifactId>
+            <version>4.0.3</version>
+        </dependency>
+
+        <dependency>
+            <groupId>org.apache.commons</groupId>
+            <artifactId>commons-lang3</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.commons</groupId>
+            <artifactId>commons-pool2</artifactId>
+        </dependency>
+
+        <dependency>
+            <groupId>commons-fileupload</groupId>
+            <artifactId>commons-fileupload</artifactId>
+            <version>1.4</version>
+            <scope>compile</scope>
+        </dependency>
+
+        <dependency>
+            <groupId>com.google.zxing</groupId>
+            <artifactId>core</artifactId>
+            <version>2.1</version>
+        </dependency>
+
+        <dependency>
+            <groupId>joda-time</groupId>
+            <artifactId>joda-time</artifactId>
+            <version>2.9.9</version>
+        </dependency>
+
+        <dependency>
+            <groupId>com.github.xingePush</groupId>
+            <artifactId>xinge</artifactId>
+            <version>1.2.2</version>
+        </dependency>
+
+
 
     </dependencies>
 </project>

+ 71 - 0
4dkankan-common-utils/src/main/java/com/fdkankan/common/constant/AppConstant.java

@@ -0,0 +1,71 @@
+package com.fdkankan.common.constant;
+
+// 4001-5000 App状态码
+public class AppConstant {
+    public static final String APP_USER_NAME = "APP_USER_NAME";
+
+    public static final int SUCCESS_CODE = 0;
+
+    public static final int FAILURE_CODE_4001 = 4001;
+    public static final String FAILURE_MSG_4001 = "验证码超时";
+
+    public static final int FAILURE_CODE_4002 = 4002;
+    public static final String FAILURE_MSG_4002 = "用户已经存在";
+
+    public static final int FAILURE_CODE_4003 = 4003;
+    public static final String FAILURE_MSG_4003 = "手机号已经被注册";
+
+    public static final int FAILURE_CODE_4004 = 4004;
+    public static final String FAILURE_MSG_4004 = "两次输入的密码不正确";
+
+    public static final int FAILURE_CODE_4005 = 4005;
+    public static final String FAILURE_MSG_4005 = "手机号与验证码不匹配";
+
+    public static final int FAILURE_CODE_4006 = 4006;
+    public static final String FAILURE_MSG_4006 = "验证码错误";
+
+    public static final int FAILURE_CODE_4007 = 4007;
+    public static final String FAILURE_MSG_4007 = "用户名不存在";
+
+    public static final int FAILURE_CODE_4008 = 4008;
+    public static final String FAILURE_MSG_4008 = "用户尚未登录";
+
+    public static final int FAILURE_CODE_4009 = 4009;
+    public static final String FAILURE_MSG_4009 = "异常错误";
+
+    public static final int FAILURE_CODE_4010 = 4010;
+    public static final String FAILURE_MSG_4010 = "绑定的相机不存在";
+
+    public static final int FAILURE_CODE_4011 = 4011;
+    public static final String FAILURE_MSG_4011 = "相机已经被绑定";
+
+    public static final int FAILURE_CODE_4012 = 4012;
+    public static final String FAILURE_MSG_4012 = "账号或密码错误";
+
+    public static final int FAILURE_CODE_4013 = 4013;
+    public static final String FAILURE_MSG_4013 = "昵称重复";
+
+    public static final int FAILURE_CODE_4014 = 4014;
+    public static final String FAILURE_MSG_4014 = "余额不足,无法生成模型,请前往网页端充值或上传时去掉生成模型选项";
+
+    public static final int FAILURE_CODE_4015 = 4015;
+    public static final String FAILURE_MSG_4015 = "昵称中包含敏感词";
+
+    public static final int FAILURE_CODE_4016 = 4016;
+    public static final String FAILURE_MSG_4016 = "参数为空";
+
+    public static final int FAILURE_CODE_4017 = 4017;
+    public static final String FAILURE_MSG_4017 = "场景为空";
+
+    public static final int FAILURE_CODE_4018 = 4018;
+    public static final String FAILURE_MSG_4018 = "场景不属于该相机";
+
+    public static final int FAILURE_CODE_4019 = 4019;
+    public static final String FAILURE_MSG_4019 = "场景序号为空";
+
+    public static final int FAILURE_CODE_4020 = 4020;
+    public static final String FAILURE_MSG_4020 = "相机未绑定用户";
+
+    public static final int FAILURE_CODE_4021 = 4021;
+    public static final String FAILURE_MSG_4021 = "开票失败,该订单已经开具发票";
+}

+ 27 - 0
4dkankan-common-utils/src/main/java/com/fdkankan/common/constant/BuildStatus.java

@@ -0,0 +1,27 @@
+package com.fdkankan.common.constant;
+
+public enum BuildStatus {
+
+    nobuild(0, "未建模"),
+    request(1, "请求建模"),
+    waiting(2, "打包失败"),
+    success(3, "建模成功"),
+    fail(-1, "建模失败");
+
+    private Integer code;
+    private String message;
+
+    private BuildStatus(Integer code, String message) {
+        this.code = code;
+        this.message = message;
+    }
+
+    public Integer code() {
+        return code;
+    }
+
+    public String message() {
+        return message;
+    }
+
+}

+ 41 - 0
4dkankan-common-utils/src/main/java/com/fdkankan/common/constant/Constant.java

@@ -0,0 +1,41 @@
+package com.fdkankan.common.constant;
+
+public class Constant {
+
+    public static final String PAY_SUBJECT = "充值(四维看看Lite双目相机)";
+
+    public static final String EXPANSION_SUBJECT = "扩充容量";
+
+    public static final String COMMERCE_SUBJECT = "商业相机";
+
+    public static final String INCREMENT_SUBJECT = "会员权益";
+
+    public static final String DOWNLOAD_SUBJECT = "场景下载";
+
+    public static int MAXPOINTS = 100000;
+
+    public static int MONEY_SCENE = 99;
+
+    public static int MONEY_HOT = 9;
+    // 3G
+//    public static String ORDINARY_BASE_SPACE_VALUE = "3221225472";
+    // 30G
+//    public static String PROFESSION_BASE_SPACE_VALUE = "32212254720";
+    // 10G
+//    public static String COMMERCE_BASE_SPACE_VALUE = "10737418240";
+    // 1G
+//    public static String DEADLINE_SPACE_VALUE_MONTH =  "1073741824";
+    // 15G
+//    public static String DEADLINE_SPACE_VALUE_YEAR = "16106127360";
+
+    // 1GB
+    public static String EXPANSION_SPACE_VALUE_1G = "1073741824";
+    // 1TB
+    public static String EXPANSION_SPACE_VALUE_1T = "1099511627776";
+    // 1PB
+    public static String EXPANSION_SPACE_VALUE_1P = "1125899906842624";
+    // 八目相机基础容量10G
+    public static String CAMERA_BASE_SPACE_VALUE = "10737418240";
+    // 八目相机商业会员容量15G
+    public static String DEADLINE_SPACE_VALUE_YEAR = "16106127360";
+}

+ 9 - 0
4dkankan-common-utils/src/main/java/com/fdkankan/common/constant/ConstantRegex.java

@@ -0,0 +1,9 @@
+package com.fdkankan.common.constant;
+
+public class ConstantRegex {
+
+    public static final String PASSWORD_REGEX = "^(?=.*\\d)(?=.*[a-z])(?=.*[A-Z])[\\da-zA-Z`~!@#$%^&*()+=|{}':;',\\[\\].<>/?~!@#¥%……&*()——+|{}【】‘;:”“’。,、?]{8,16}$";
+
+    public static final String EMAIL_REGEX = "^[A-Za-z\\d]+([_.-][A-Za-z\\d]+)*@([A-Za-z\\d]+[-.])+[A-Za-z\\d]{2,4}$";
+
+}

+ 25 - 0
4dkankan-common-utils/src/main/java/com/fdkankan/common/constant/DownloadStatus.java

@@ -0,0 +1,25 @@
+package com.fdkankan.common.constant;
+
+public enum DownloadStatus {
+
+    DOWNLOADING(0, "下载中"),
+    SUCCESS(1, "下载成功"),
+    FAILD(2, "下载失败");
+
+    private Integer code;
+    private String message;
+
+    private DownloadStatus(Integer code, String message) {
+        this.code = code;
+        this.message = message;
+    }
+
+    public Integer code() {
+        return code;
+    }
+
+    public String message() {
+        return message;
+    }
+
+}

+ 18 - 0
4dkankan-common-utils/src/main/java/com/fdkankan/common/constant/LoginType.java

@@ -0,0 +1,18 @@
+package com.fdkankan.common.constant;
+
+public enum LoginType {
+
+    USER("User"),  MANAGER("Manager"), AGENT("Agent"), APP("App");
+
+    private String type;
+
+    private LoginType(String type) {
+        this.type = type;
+    }
+
+    @Override
+    public String toString() {
+        return this.type.toString();
+    }
+
+}

+ 17 - 0
4dkankan-common-utils/src/main/java/com/fdkankan/common/constant/OrderConstant.java

@@ -0,0 +1,17 @@
+package com.fdkankan.common.constant;
+
+// 8001-9000 订单状态码
+public class OrderConstant {
+    public static final int FAILURE_CODE_8001 = 8001;
+    public static final String FAILURE_MSG_8001 = "订单不存在";
+
+
+    public static final int FAILURE_CODE_8002 = 8002;
+    public static final String FAILURE_MSG_8002 = "支付失败";
+
+    public static final int FAILURE_CODE_8003 = 8003;
+    public static final String FAILURE_MSG_8003 = "开票金额超过范围";
+
+    public static final int FAILURE_CODE_8004 = 8004;
+    public static final String FAILURE_MSG_8004 = "支付方式异常";
+}

+ 26 - 0
4dkankan-common-utils/src/main/java/com/fdkankan/common/constant/PayStatus.java

@@ -0,0 +1,26 @@
+package com.fdkankan.common.constant;
+
+public enum PayStatus {
+
+    NOT_PAY(0, "未付款"),
+    PAY(1, "已付款"),
+    ARREARS(-1, "欠费"),
+    NO_CAPACITY(-2, "容量不足");
+
+    private Integer code;
+    private String message;
+
+    private PayStatus(Integer code, String message) {
+        this.code = code;
+        this.message = message;
+    }
+
+    public Integer code() {
+        return code;
+    }
+
+    public String message() {
+        return message;
+    }
+
+}

+ 24 - 0
4dkankan-common-utils/src/main/java/com/fdkankan/common/constant/RecStatus.java

@@ -0,0 +1,24 @@
+package com.fdkankan.common.constant;
+
+public enum RecStatus {
+
+    VALID("A", "生效"),
+    DISABLE("I", "禁用");
+
+    private String code;
+    private String message;
+
+    private RecStatus(String code, String message) {
+        this.code = code;
+        this.message = message;
+    }
+
+    public String code() {
+        return code;
+    }
+
+    public String message() {
+        return message;
+    }
+
+}

+ 111 - 0
4dkankan-common-utils/src/main/java/com/fdkankan/common/constant/SceneConstant.java

@@ -0,0 +1,111 @@
+
+package com.fdkankan.common.constant;
+
+// 5001-6000 场景状态码
+public class SceneConstant {
+
+    public static final int FAILURE_CODE_5001 = 5001;
+    public static final String FAILURE_MSG_5001 = "modeldata.json为空";
+
+    public static final int FAILURE_CODE_5002 = 5002;
+    public static final String FAILURE_MSG_5002 = "order值为空";
+
+    public static final int FAILURE_CODE_5003 = 5003;
+    public static final String FAILURE_MSG_5003 = "guideSid或order值为空";
+
+    public static final int FAILURE_CODE_5004 = 5004;
+    public static final String FAILURE_MSG_5004 = "guideSid或guideName值为空";
+
+    public static final int FAILURE_CODE_5005 = 5005;
+    public static final String FAILURE_MSG_5005 = "场景为空";
+
+    public static final int FAILURE_CODE_5006 = 5006;
+    public static final String FAILURE_MSG_5006 = "余额不足";
+
+    public static final int FAILURE_CODE_5007 = 5007;
+    public static final String FAILURE_MSG_5007 = "非八目场景";
+
+    public static final int FAILURE_CODE_5008 = 5008;
+    public static final String FAILURE_MSG_5008 = "该场景已经被封存,无法删除";
+
+    public static final int FAILURE_CODE_5009 = 5009;
+    public static final String FAILURE_MSG_5009 = "场景被删除";
+
+	public static final int FAILURE_CODE_5010 = 5010;
+    public static final String FAILURE_MSG_5010 = "场景不属于该相机";
+
+    public static final int FAILURE_CODE_5011 = 5011;
+    public static final String FAILURE_MSG_5011 = "创建";
+
+    public static final int FAILURE_CODE_5012 = 5012;
+    public static final String FAILURE_MSG_5012 = "数据不正常";
+
+    public static final int FAILURE_CODE_5013 = 5013;
+    public static final String FAILURE_MSG_5013 = "场景对应的用户名为空";
+
+    public static final int FAILURE_CODE_5014 = 5014;
+    public static final String FAILURE_MSG_5014 = "该用户无权操作该场景";
+
+    public static final int FAILURE_CODE_5015 = 5015;
+    public static final String FAILURE_MSG_5015 = "该场景不属于当前登录账号";
+
+    public static final int FAILURE_CODE_5016 = 5016;
+    public static final String FAILURE_MSG_5016 = "热点外链场景不对";
+
+    public static final int FAILURE_CODE_5017 = 5017;
+    public static final String FAILURE_MSG_5017 = "*上传模型失败,请参照右侧教程";
+
+    public static final int FAILURE_CODE_5018 = 5018;
+    public static final String FAILURE_MSG_5018 = "zip文件只能有一层目录或无目录";
+
+    public static final int FAILURE_CODE_5019 = 5019;
+    public static final String FAILURE_MSG_5019 = "必须有且仅有一个obj和mtl文件";
+
+    public static final int FAILURE_CODE_5020 = 5020;
+    public static final String FAILURE_MSG_5020 = "贴图需控制在1.5M以内,obj文件需要控制在20M以内。";
+
+    public static final int FAILURE_CODE_5021 = 5021;
+    public static final String FAILURE_MSG_5021 = "场景密钥不正确";
+
+    public static final int FAILURE_CODE_5022 = 5022;
+    public static final String FAILURE_MSG_5022 = "上传文件格式,名称不一致";
+
+    public static final int FAILURE_CODE_5023 = 5023;
+    public static final String FAILURE_MSG_5023 = "上传文件格式不正确,只能是jpg或mp4格式";
+
+    public static final int FAILURE_CODE_5024 = 5024;
+    public static final String FAILURE_MSG_5024 = "有场景打包中,请稍后重试";
+
+    public static final int FAILURE_CODE_5025 = 5025;
+    public static final String FAILURE_MSG_5025 = "数据包不存在,请先打成zip包";
+
+    public static final int FAILURE_CODE_5026 = 5026;
+    public static final String FAILURE_MSG_5026 = "上传的压缩包类型不正确";
+
+    public static final int FAILURE_CODE_5027 = 5027;
+    public static final String FAILURE_MSG_5027 = "文件夹不存在";
+
+    public static final int FAILURE_CODE_5028 = 5028;
+    public static final String FAILURE_MSG_5028 = "无权修改该文件夹";
+
+    public static final int FAILURE_CODE_5029 = 5029;
+    public static final String FAILURE_MSG_5029 = "场景下载失败,请稍后重试";
+
+    public static final int FAILURE_CODE_5030 = 5030;
+    public static final String FAILURE_MSG_5030 = "同级文件夹名称不能重复";
+
+    public static final int FAILURE_CODE_5031 = 5031;
+    public static final String FAILURE_MSG_5031 = "场景打包中不能重复操作";
+
+    public static final int FAILURE_CODE_5032 = 5032;
+    public static final String FAILURE_MSG_5032 = "三维家打包记录不存在";
+
+    public static final int FAILURE_CODE_5033 = 5033;
+    public static final String FAILURE_MSG_5033 = "该场景正在计算中";
+
+    public static final int FAILURE_CODE_5034 = 5034;
+    public static final String FAILURE_MSG_5034 = "该场景已封存";
+
+    public static final int FAILURE_CODE_5035 = 5035;
+    public static final String FAILURE_MSG_5035 = "任务已存在";
+}

+ 25 - 0
4dkankan-common-utils/src/main/java/com/fdkankan/common/constant/SceneEditType.java

@@ -0,0 +1,25 @@
+package com.fdkankan.common.constant;
+
+public enum SceneEditType {
+
+    UPDATE(0, "修改"),
+    ADD(1, "添加"),
+    DELETE(-1, "删除");
+
+    private Integer code;
+    private String message;
+
+    private SceneEditType(Integer code, String message) {
+        this.code = code;
+        this.message = message;
+    }
+
+    public Integer code() {
+        return code;
+    }
+
+    public String message() {
+        return message;
+    }
+
+}

+ 26 - 0
4dkankan-common-utils/src/main/java/com/fdkankan/common/constant/SceneStatus.java

@@ -0,0 +1,26 @@
+package com.fdkankan.common.constant;
+
+public enum SceneStatus {
+
+    wait(0, "未建好"),
+    SUCCESS(1, "已建好"),
+    FAILD(-1, "出错"),
+    NO_DISPLAY(-2, "不要在官网上显示");
+
+    private Integer code;
+    private String message;
+
+    private SceneStatus(Integer code, String message) {
+        this.code = code;
+        this.message = message;
+    }
+
+    public Integer code() {
+        return code;
+    }
+
+    public String message() {
+        return message;
+    }
+
+}

+ 29 - 0
4dkankan-common-utils/src/main/java/com/fdkankan/common/constant/SceneType.java

@@ -0,0 +1,29 @@
+package com.fdkankan.common.constant;
+
+public enum SceneType {
+
+    OTHER(0, "其它"),
+    WB(1, "文博"),
+    DC(2, "地产"),
+    DS(3, "电商"),
+    CY(4, "餐饮"),
+    JU(5, "家居"),
+    YJHZXNFY(99, "一件换装虚拟房源");
+
+    private Integer code;
+    private String message;
+
+    private SceneType(Integer code, String message) {
+        this.code = code;
+        this.message = message;
+    }
+
+    public Integer code() {
+        return code;
+    }
+
+    public String message() {
+        return message;
+    }
+
+}

+ 24 - 0
4dkankan-common-utils/src/main/java/com/fdkankan/common/constant/TbStatus.java

@@ -0,0 +1,24 @@
+package com.fdkankan.common.constant;
+
+public enum TbStatus {
+
+    VALID(0, "有效的"),
+    DELETE(1, "已删除");
+
+    private Integer code;
+    private String message;
+
+    private TbStatus(Integer code, String message) {
+        this.code = code;
+        this.message = message;
+    }
+
+    public Integer code() {
+        return code;
+    }
+
+    public String message() {
+        return message;
+    }
+
+}

+ 25 - 0
4dkankan-common-utils/src/main/java/com/fdkankan/common/constant/UploadStatus.java

@@ -0,0 +1,25 @@
+package com.fdkankan.common.constant;
+
+public enum UploadStatus {
+
+    UPLOADING(0, "上传中"),
+    SUCCESS(1, "上传成功"),
+    FAILD(-1, "上传失败");
+
+    private Integer code;
+    private String message;
+
+    private UploadStatus(Integer code, String message) {
+        this.code = code;
+        this.message = message;
+    }
+
+    public Integer code() {
+        return code;
+    }
+
+    public String message() {
+        return message;
+    }
+
+}

+ 26 - 0
4dkankan-common-utils/src/main/java/com/fdkankan/common/constant/ZipStatus.java

@@ -0,0 +1,26 @@
+package com.fdkankan.common.constant;
+
+public enum ZipStatus {
+
+    DOING(0, "打包中"),
+    SUCCESS(1, "打包完成"),
+    FAILD(2, "打包失败"),
+    OTHER(3, "");
+
+    private Integer code;
+    private String message;
+
+    private ZipStatus(Integer code, String message) {
+        this.code = code;
+        this.message = message;
+    }
+
+    public Integer code() {
+        return code;
+    }
+
+    public String message() {
+        return message;
+    }
+
+}

+ 602 - 0
4dkankan-common-utils/src/main/java/com/fdkankan/common/proto/format/SmileFormat.java

@@ -0,0 +1,602 @@
+package com.fdkankan.common.proto.format;
+/* 
+	Copyright (c) 2009, Orbitz World Wide
+	All rights reserved.
+
+	Redistribution and use in source and binary forms, with or without modification, 
+	are permitted provided that the following conditions are met:
+
+		* Redistributions of source code must retain the above copyright notice, 
+		  this list of conditions and the following disclaimer.
+		* Redistributions in binary form must reproduce the above copyright notice, 
+		  this list of conditions and the following disclaimer in the documentation 
+		  and/or other materials provided with the distribution.
+		* Neither the name of the Orbitz World Wide nor the names of its contributors 
+		  may be used to endorse or promote products derived from this software 
+		  without specific prior written permission.
+
+	THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+	"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+	LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+	A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+	OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+	SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+	LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+	DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+	THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+	(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+	OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+
+import com.google.protobuf.*;
+import com.google.protobuf.Descriptors.Descriptor;
+import com.google.protobuf.Descriptors.EnumDescriptor;
+import com.google.protobuf.Descriptors.EnumValueDescriptor;
+import com.google.protobuf.Descriptors.FieldDescriptor;
+import org.codehaus.jackson.JsonGenerator;
+import org.codehaus.jackson.JsonParseException;
+import org.codehaus.jackson.JsonParser;
+import org.codehaus.jackson.JsonToken;
+import org.codehaus.jackson.smile.SmileFactory;
+import org.codehaus.jackson.smile.SmileGenerator;
+import org.codehaus.jackson.smile.SmileParser;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.math.BigInteger;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Locale;
+import java.util.Map;
+import java.util.regex.Pattern;
+
+/**
+ * Provide ascii text parsing and formatting support for proto2 instances. The implementation
+ * largely follows google/protobuf/text_format.cc.
+ * <p>
+ * (c) 2011 Neustar, Inc. All Rights Reserved.
+ *
+ * @author jeffrey.damick@neustar.biz Jeffrey Damick
+ *         Based on the original code by:
+ * @author eliran.bivas@gmail.com Eliran Bivas
+ * @author aantonov@orbitz.com Alex Antonov
+ *         <p/>
+ * @author wenboz@google.com Wenbo Zhu
+ * @author kenton@google.com Kenton Varda
+ */
+public class SmileFormat {
+    private static SmileFactory smileFactory = new SmileFactory();
+	
+		
+    /**
+     * Outputs a Smile representation of the Protocol Message supplied into the parameter output.
+     * (This representation is the new version of the classic "ProtocolPrinter" output from the
+     * original Protocol Buffer system)
+     */
+    public static void print(Message message, OutputStream output) throws IOException {
+        JsonGenerator generator = createGenerator(output);
+    	print(message, generator);
+    	generator.close();
+    }
+    
+    /**
+     * Outputs a Smile representation of the Protocol Message supplied into the parameter output.
+     * (This representation is the new version of the classic "ProtocolPrinter" output from the
+     * original Protocol Buffer system)
+     */
+    public static void print(Message message, JsonGenerator generator) throws IOException {
+    	generator.writeStartObject();
+    	printMessage(message, generator);
+        generator.writeEndObject();
+        generator.flush();
+    }
+
+    /**
+     * Outputs a Smile representation of {@code fields} to {@code output}.
+     */
+    public static void print(UnknownFieldSet fields, OutputStream output) throws IOException {
+    	JsonGenerator generator = createGenerator(output);
+    	generator.writeStartObject();
+    	printUnknownFields(fields, generator);
+        generator.writeEndObject();
+        generator.close();
+    }
+    
+    
+    
+    /**
+     * Parse a text-format message from {@code input} and merge the contents into {@code builder}.
+     */
+    public static void merge(InputStream input, Message.Builder builder) throws IOException {
+        merge(input, ExtensionRegistry.getEmptyRegistry(), builder);
+    }
+
+        
+    /**
+     * Parse a text-format message from {@code input} and merge the contents into {@code builder}.
+     * Extensions will be recognized if they are registered in {@code extensionRegistry}.
+     * @throws IOException 
+     */
+    public static void merge(InputStream input,
+                             ExtensionRegistry extensionRegistry,
+                             Message.Builder builder) throws IOException {
+    	
+    	SmileParser parser = smileFactory.createJsonParser(input); 
+    	merge(parser, extensionRegistry, builder);
+    }
+    
+    /**
+     * Parse a text-format message from {@code input} and merge the contents into {@code builder}.
+     * Extensions will be recognized if they are registered in {@code extensionRegistry}.
+     * @throws IOException 
+     */
+    public static void merge(JsonParser parser,                 
+    						 ExtensionRegistry extensionRegistry,
+                             Message.Builder builder) throws IOException {
+    	
+        JsonToken token = parser.nextToken();
+        if (token.equals(JsonToken.START_OBJECT)) {
+        	token = parser.nextToken();
+        }
+        while (token != null && !token.equals(JsonToken.END_OBJECT)) {
+        	mergeField(parser, extensionRegistry, builder);
+        	token = parser.nextToken();
+        }
+        
+        // Test to make sure the tokenizer has reached the end of the stream.
+        if (parser.nextToken() != null) {
+            throw new RuntimeException("Expecting the end of the stream, but there seems to be more data!  Check the input for a valid JSON format.");
+        }
+    }
+    
+    
+    
+    protected static JsonGenerator createGenerator(OutputStream output) throws IOException {
+    	SmileGenerator generator = smileFactory.createJsonGenerator(output);
+    	generator.enable(SmileGenerator.Feature.WRITE_HEADER);
+    	generator.enable(SmileGenerator.Feature.WRITE_END_MARKER);
+    	return generator;
+    }
+
+    
+    protected static void printMessage(Message message, JsonGenerator generator) throws IOException {
+
+        for (Iterator<Map.Entry<FieldDescriptor, Object>> iter = message.getAllFields().entrySet().iterator(); iter.hasNext();) {
+            Map.Entry<FieldDescriptor, Object> field = iter.next();
+            printField(field.getKey(), field.getValue(), generator);
+        }
+        printUnknownFields(message.getUnknownFields(), generator);
+    }
+
+    public static void printField(FieldDescriptor field, Object value, JsonGenerator generator) throws IOException {
+
+        printSingleField(field, value, generator);
+    }
+
+    private static void printSingleField(FieldDescriptor field,
+                                         Object value,
+                                         JsonGenerator generator) throws IOException {
+        if (field.isExtension()) {
+            // We special-case MessageSet elements for compatibility with proto1.
+            if (field.getContainingType().getOptions().getMessageSetWireFormat()
+                && (field.getType() == FieldDescriptor.Type.MESSAGE) && (field.isOptional())
+                // object equality
+                && (field.getExtensionScope() == field.getMessageType())) {
+                generator.writeFieldName(field.getMessageType().getFullName());
+            } else {
+            	// extensions will have '.' in them, while normal fields wont..
+            	generator.writeFieldName(field.getFullName());
+            }
+        } else {
+            if (field.getType() == FieldDescriptor.Type.GROUP) {
+                // Groups must be serialized with their original capitalization.
+                generator.writeFieldName(field.getMessageType().getName());
+            } else {
+                generator.writeFieldName(field.getName());
+            }
+        }
+
+        // Done with the name, on to the value
+        if (field.isRepeated()) {
+            // Repeated field. Print each element.
+            generator.writeStartArray();
+            for (Iterator<?> iter = ((List<?>) value).iterator(); iter.hasNext();) {
+                printFieldValue(field, iter.next(), generator);
+            }
+            generator.writeEndArray();
+        } else {
+            printFieldValue(field, value, generator);
+        }
+    }
+
+    private static void printFieldValue(FieldDescriptor field, Object value, JsonGenerator generator) throws IOException {
+    	// TODO: look at using field.getType().getJavaType(), to simplify this..
+    	switch (field.getType()) {
+            case INT32:
+            case SINT32:
+            case SFIXED32:
+            	generator.writeNumber((Integer)value);
+            	break;
+            
+            case INT64:
+            case SINT64:
+            case SFIXED64:
+            	generator.writeNumber((Long)value);
+            	break;
+            	
+            case FLOAT:
+            	generator.writeNumber((Float)value);
+            	break;
+            	
+            case DOUBLE:
+            	generator.writeNumber((Double)value);
+            	break;
+            	
+            case BOOL:
+                // Good old toString() does what we want for these types.
+                generator.writeBoolean((Boolean)value);
+                break;
+
+            case UINT32:
+            case FIXED32:
+                generator.writeNumber(unsignedInt((Integer) value));
+                break;
+
+            case UINT64:
+            case FIXED64:
+                generator.writeNumber(unsignedLong((Long) value));
+                break;
+
+            case STRING:
+            	generator.writeString((String) value);
+                break;
+
+            case BYTES: {
+            	// Here we break with JsonFormat - since there is an issue with non-utf8 bytes..
+            	generator.writeBinary(((ByteString)value).toByteArray());
+                break;
+            }
+
+            case ENUM: {
+            	generator.writeString(((EnumValueDescriptor) value).getName());
+                break;
+            }
+
+            case MESSAGE:
+            case GROUP:
+            	generator.writeStartObject();
+                printMessage((Message) value, generator);
+                generator.writeEndObject();
+                break;
+        }
+    }
+
+    protected static void printUnknownFields(UnknownFieldSet unknownFields, JsonGenerator generator) throws IOException {
+        for (Map.Entry<Integer, UnknownFieldSet.Field> entry : unknownFields.asMap().entrySet()) {
+            UnknownFieldSet.Field field = entry.getValue();
+            
+            generator.writeArrayFieldStart(entry.getKey().toString());
+            for (long value : field.getVarintList()) {
+                generator.writeNumber(value);
+            }
+            for (int value : field.getFixed32List()) {
+                generator.writeNumber(value);
+            }
+            for (long value : field.getFixed64List()) {
+                generator.writeNumber(value);
+            }
+            for (ByteString value : field.getLengthDelimitedList()) {
+            	// here we break with the JsonFormat to support non-utf8 bytes
+            	generator.writeBinary(value.toByteArray());
+            }
+            for (UnknownFieldSet value : field.getGroupList()) {
+                generator.writeStartObject();
+                printUnknownFields(value, generator);
+                generator.writeEndObject();
+            }
+            generator.writeEndArray();
+        }
+    }
+
+
+
+    // =================================================================
+    // Parsing
+   
+    private static final Pattern DIGITS = Pattern.compile(
+          "[0-9]",
+          Pattern.CASE_INSENSITIVE);
+
+    /**
+     * Parse a single field from {@code parser} and merge it into {@code builder}. If a ',' is
+     * detected after the field ends, the next field will be parsed automatically
+     * @throws IOException 
+     * @throws JsonParseException 
+     */
+    protected static void mergeField(JsonParser parser,
+                                   ExtensionRegistry extensionRegistry,
+                                   Message.Builder builder) throws JsonParseException, IOException {
+        FieldDescriptor field = null;
+        Descriptor type = builder.getDescriptorForType();
+        boolean unknown = false;
+        ExtensionRegistry.ExtensionInfo extension = null;
+        JsonToken token = parser.getCurrentToken();
+
+        if (token != null) {
+            String name = parser.getCurrentName();
+            
+            if (name.contains(".")) {
+            	// should be an extension
+            	extension = extensionRegistry.findExtensionByName(name);
+                if (extension == null) {
+                    throw new RuntimeException("Extension \""
+                    		+ name + "\" not found in the ExtensionRegistry.");
+                } else if (extension.descriptor.getContainingType() != type) {
+                    throw new RuntimeException("Extension \"" + name
+                    		+ "\" does not extend message type \""
+                    		+ type.getFullName() + "\".");
+                }
+
+            	field = extension.descriptor;
+            } else {
+            	field = type.findFieldByName(name);
+            }
+
+            // Group names are expected to be capitalized as they appear in the
+            // .proto file, which actually matches their type names, not their field
+            // names.
+            if (field == null) {
+                // Explicitly specify US locale so that this code does not break when
+                // executing in Turkey.
+                String lowerName = name.toLowerCase(Locale.US);
+                field = type.findFieldByName(lowerName);
+                // If the case-insensitive match worked but the field is NOT a group,
+                if ((field != null) && (field.getType() != FieldDescriptor.Type.GROUP)) {
+                    field = null;
+                }
+            }
+            // Again, special-case group names as described above.
+            if ((field != null) && (field.getType() == FieldDescriptor.Type.GROUP)
+                && !field.getMessageType().getName().equals(name)
+                && !field.getMessageType().getFullName().equalsIgnoreCase(name) /* extension */) {
+                field = null;
+            }
+
+            // Last try to lookup by field-index if 'name' is numeric,
+            // which indicates a possible unknown field
+            if (field == null && DIGITS.matcher(name).matches()) {
+                field = type.findFieldByNumber(Integer.parseInt(name));
+                unknown = true;
+            }
+
+            // no throwing exceptions if field not found, since it could be a different version.
+            if (field == null) {
+            	UnknownFieldSet.Builder unknownsBuilder = UnknownFieldSet.newBuilder();
+            	handleMissingField(name, parser, extensionRegistry, unknownsBuilder);
+            	builder.setUnknownFields(unknownsBuilder.build());
+            }
+        }
+
+        if (field != null) {
+        	token = parser.nextToken();
+        	
+            boolean array = token.equals(JsonToken.START_ARRAY);
+
+            if (array) {
+            	token = parser.nextToken();
+                while (!token.equals(JsonToken.END_ARRAY)) {
+                    handleValue(parser, extensionRegistry, builder, field, extension, unknown);
+                    token = parser.nextToken();
+                }
+            } else {
+                handleValue(parser, extensionRegistry, builder, field, extension, unknown);
+            }
+        }
+    }
+
+    private static void handleMissingField(String fieldName, JsonParser parser,
+                                           ExtensionRegistry extensionRegistry,
+                                           UnknownFieldSet.Builder builder) throws IOException {
+    	
+        JsonToken token = parser.nextToken();
+        if (token.equals(JsonToken.START_OBJECT)) {
+            // Message structure
+        	token = parser.nextToken(); // skip name
+        	while (token != null && !token.equals(JsonToken.END_OBJECT)) {
+                handleMissingField(fieldName, parser, extensionRegistry, builder);
+                token = parser.nextToken(); // get } or field name
+            }
+        } else if (token.equals(JsonToken.START_ARRAY)) {
+            // Collection
+            do {
+                handleMissingField(fieldName, parser, extensionRegistry, builder);
+                token = parser.getCurrentToken(); // got value or ]
+            } while (token != null && !token.equals(JsonToken.END_ARRAY));
+        } else {
+            // Primitive value
+        	// NULL, INT, BOOL, STRING
+        	// nothing to do..
+        }
+    }
+
+    private static void handleValue(JsonParser parser,
+                                    ExtensionRegistry extensionRegistry,
+                                    Message.Builder builder,
+                                    FieldDescriptor field,
+                                    ExtensionRegistry.ExtensionInfo extension,
+                                    boolean unknown) throws IOException {
+
+        Object value = null;
+        if (field.getJavaType() == FieldDescriptor.JavaType.MESSAGE) {
+            value = handleObject(parser, extensionRegistry, builder, field, extension, unknown);
+        } else {
+            value = handlePrimitive(parser, field);
+        }
+        if (value != null) {
+            if (field.isRepeated()) {
+                builder.addRepeatedField(field, value);
+            } else {
+                builder.setField(field, value);
+            }
+        }
+    }
+
+    private static Object handlePrimitive(JsonParser parser, FieldDescriptor field) throws IOException {
+        Object value = null;
+        
+        JsonToken token = parser.getCurrentToken();
+        
+        if (token.equals(JsonToken.VALUE_NULL)) {
+            return value;
+        }
+        
+        switch (field.getType()) {
+            case INT32:
+            case SINT32:
+            case SFIXED32:
+            	value = parser.getIntValue();
+                break;
+
+            case INT64:
+            case SINT64:
+            case SFIXED64:
+            	value = parser.getLongValue();
+                break;
+
+            case UINT32:
+            case FIXED32:
+            	int valueInt = parser.getIntValue();
+            	if (valueInt < 0) {
+            		throw new NumberFormatException("Number must be positive: " + valueInt);
+            	}
+            	value = valueInt;
+                break;
+
+            case UINT64:
+            case FIXED64:
+            	long valueLong = parser.getLongValue();
+            	if (valueLong < 0) {
+            		throw new NumberFormatException("Number must be positive: " + valueLong);
+            	}
+            	value = valueLong;
+                break;
+
+            case FLOAT:
+            	value = parser.getFloatValue();
+                break;
+
+            case DOUBLE:
+            	value = parser.getDoubleValue();
+                break;
+
+            case BOOL:
+            	value = parser.getBooleanValue();
+                break;
+
+            case STRING:
+            	value = parser.getText();
+                break;
+
+            case BYTES:
+            	value = ByteString.copyFrom(parser.getBinaryValue());
+                break;
+
+            case ENUM: {
+                EnumDescriptor enumType = field.getEnumType();
+                if (token.equals(JsonToken.VALUE_NUMBER_INT)) {
+                    int number = parser.getIntValue();
+                    value = enumType.findValueByNumber(number);
+                    if (value == null) {
+                        throw new RuntimeException("Enum type \""
+                        		+ enumType.getFullName()
+                        		+ "\" has no value with number "
+                        		+ number + ".");
+                    }
+                } else {
+                    String id = parser.getText();
+                    value = enumType.findValueByName(id);
+                    if (value == null) {
+                    	throw new RuntimeException("Enum type \""
+                    			+ enumType.getFullName()
+                    			+ "\" has no value named \""
+                    			+ id + "\".");
+                    }
+                }
+                break;
+            }
+
+            case MESSAGE:
+            case GROUP:
+                throw new RuntimeException("Can't get here.");
+        }
+        return value;
+    }
+    
+
+    private static Object handleObject(JsonParser parser,
+                                       ExtensionRegistry extensionRegistry,
+                                       Message.Builder builder,
+                                       FieldDescriptor field,
+                                       ExtensionRegistry.ExtensionInfo extension,
+                                       boolean unknown) throws IOException {
+
+        Message.Builder subBuilder;
+        if (extension == null) {
+            subBuilder = builder.newBuilderForField(field);
+        } else {
+            subBuilder = extension.defaultInstance.newBuilderForType();
+        }
+
+        JsonToken token = parser.getCurrentToken();
+
+        if (unknown) {
+        	ByteString data = ByteString.copyFrom(parser.getBinaryValue());
+            try {
+                subBuilder.mergeFrom(data);
+                return subBuilder.build();
+            } catch (InvalidProtocolBufferException e) {
+                throw new RuntimeException("Failed to build " + field.getFullName() + " from " + data);
+            }
+        }
+
+        //token = parser.nextToken();
+        if (token.equals(JsonToken.START_OBJECT)) {
+	        token = parser.nextToken();
+	        while (token != null && !token.equals(JsonToken.END_OBJECT)) {
+	            mergeField(parser, extensionRegistry, subBuilder);
+	            token = parser.nextToken();
+	        }
+        }
+        return subBuilder.build();
+    }
+
+    // =================================================================
+    // Utility functions
+    //
+    // Some of these methods are package-private because Descriptors.java uses
+    // them.
+    
+    /**
+     * Convert an unsigned 32-bit integer to a string.
+     */
+    private static Integer unsignedInt(int value) {
+        if (value < 0) {
+            return (int) ((value) & 0x00000000FFFFFFFFL);
+        }
+        return value;
+    }
+
+    /**
+     * Convert an unsigned 64-bit integer to a string.
+     */
+    private static Long unsignedLong(long value) {
+        if (value < 0) {
+            // Pull off the most-significant bit so that BigInteger doesn't think
+            // the number is negative, then set it again using setBit().
+            return BigInteger.valueOf(value & 0x7FFFFFFFFFFFFFFFL).setBit(63).longValue();
+        }
+        return value;
+    }
+}

+ 45 - 0
4dkankan-common-utils/src/main/java/com/fdkankan/common/util/AesUtil.java

@@ -0,0 +1,45 @@
+package com.fdkankan.common.util;
+
+import com.aliyuncs.utils.Base64Helper;
+
+import javax.crypto.Cipher;
+import javax.crypto.spec.IvParameterSpec;
+import javax.crypto.spec.SecretKeySpec;
+
+public class AesUtil {
+    /**
+     * @author miracle.qu
+     * AES算法加密明文
+     * @param data 明文
+     * @param key 密钥,长度16
+     * @param iv 偏移量,长度16
+     * @return 密文
+     */
+    public static String encryptAES(String data,String key,String iv) throws Exception {
+        try {
+            Cipher cipher = Cipher.getInstance("AES/CBC/NoPadding");
+            int blockSize = cipher.getBlockSize();
+            byte[] dataBytes = data.getBytes();
+            int plaintextLength = dataBytes.length;
+
+            if (plaintextLength % blockSize != 0) {
+                plaintextLength = plaintextLength + (blockSize - (plaintextLength % blockSize));
+            }
+
+            byte[] plaintext = new byte[plaintextLength];
+            System.arraycopy(dataBytes, 0, plaintext, 0, dataBytes.length);
+
+            SecretKeySpec keyspec = new SecretKeySpec(key.getBytes(), "AES");
+            IvParameterSpec ivspec = new IvParameterSpec(iv.getBytes());
+
+            cipher.init(Cipher.ENCRYPT_MODE, keyspec, ivspec);
+            byte[] encrypted = cipher.doFinal(plaintext);
+
+            return Base64Helper.encode(encrypted).trim();
+
+        } catch (Exception e) {
+            e.printStackTrace();
+            return null;
+        }
+    }
+}

+ 1 - 1
4dkankan-common-utils/src/main/java/com/fdkankan/common/utils/Base64Converter.java

@@ -1,4 +1,4 @@
-package com.fdkankan.common.utils;
+package com.fdkankan.common.util;
 
 import java.io.UnsupportedEncodingException;
 import java.util.Base64;

+ 591 - 0
4dkankan-common-utils/src/main/java/com/fdkankan/common/util/ComputerUtil.java

@@ -0,0 +1,591 @@
+package com.fdkankan.common.util;
+
+import com.alibaba.fastjson.JSONArray;
+import com.alibaba.fastjson.JSONObject;
+import com.fdkankan.common.constant.ConstantFileName;
+import com.fdkankan.common.constant.ConstantFilePath;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.stereotype.Component;
+
+import java.io.File;
+import java.util.*;
+
+/**
+ * 生成场景和计算场景
+ * Created by Hb_zzZ on 2019/5/8.
+ */
+@Slf4j
+@Component
+public class ComputerUtil {
+
+
+    public static Map<String,String> computer(String projectNum, String path, String buildType) throws Exception{
+        Map<String,String> map = new HashMap<String,String>();
+        path = path.replace("//", "/");
+
+        log.info("开始建模:"+projectNum);
+        //构建算法isModel去掉,因此改成空字符串
+        if("V2".equals(buildType)){
+            CreateObjUtil.build3dModelOld(path, "");
+        }
+        if("V3".equals(buildType)){
+            CreateObjUtil.build3dModel(path, "");
+//        CreateObjUtil.build3dModel(unicode, "");
+        }
+        log.info("建模完成转换数据:"+projectNum);
+
+        boolean vision2 = false;
+        //读取upload文件,检验需要上传的文件是否存在
+        String uploadData = FileUtils.readFile(path + File.separator + "results" +File.separator+"upload.json");
+        JSONObject uploadJson = null;
+        JSONArray array = null;
+        if(uploadData!=null) {
+            uploadJson = JSONObject.parseObject(uploadData);
+            array = uploadJson.getJSONArray("upload");
+        }
+        if(array == null){
+            String instanceId = FileUtils.readFile("/opt/hosts/hosts.txt");
+            FileUtils.writeFile(path + File.separator + "javaErrorNow.log", instanceId + ":计算错误!");
+
+            Thread.sleep(10000L);
+            FileUtils.writeFile(path + File.separator + "javaError.log", instanceId + ":计算错误!");
+            throw new Exception("upload.json数据出错");
+        }
+        JSONObject fileJson = null;
+        String fileName = "";
+        String meshfix = "";  //双模型时候会有改文件路径
+        for(int i = 0, len = array.size(); i < len; i++){
+            fileJson = array.getJSONObject(i);
+            fileName = fileJson.getString("file");
+            //文件不存在抛出异常
+            if(!new File(path + File.separator + "results" +File.separator + fileName).exists()){
+                throw new Exception(path + File.separator + "results" +File.separator + fileName+"文件不存在");
+            }
+
+            //判断是否有vision2.txt
+            if("vision2.txt".equals(fileName)){
+                vision2 = true;
+            }
+
+            //tex文件夹
+            if(fileJson.getIntValue("clazz") == 2 && !fileJson.containsKey("pack-file")){
+                if(fileName.contains("meshfix.txt")){
+                    meshfix = fileName;
+                }else {
+                    map.put(path + File.separator + "results" +File.separator+ fileName,"images/images"+
+                            projectNum+"/"+ ConstantFileName.modelUUID+"_50k_texture_jpg_high1/"+fileName.replace("tex/", ""));
+                }
+                continue;
+            }
+
+            //high文件夹
+            if(fileJson.getIntValue("clazz") == 3){
+                map.put(path + File.separator + "results" +File.separator+ fileName,"images/images"+
+                        projectNum+"/pan/high/"+ fileName.replace("high/", ""));
+                continue;
+            }
+            //low文件夹
+            if(fileJson.getIntValue("clazz") == 4){
+                map.put(path + File.separator + "results" +File.separator+ fileName,"images/images"+
+                        projectNum+"/pan/low/"+ fileName.replace("low/", ""));
+                continue;
+            }
+
+            //tiles文件夹,亚马逊没有裁剪图片api,不需要上传4k图
+//            if(fileJson.getIntValue("clazz") == 5 && !"s3".equals(ossType)){
+//                map.put(path + File.separator + "results" + File.separator+ fileName,"images/images"+
+//                        projectNum+ File.separator + fileName);
+//                continue;
+//            }
+            if(fileJson.getIntValue("clazz") == 5 ){
+                map.put(path + File.separator + "results" + File.separator+ fileName,"images/images"+
+                        projectNum+ File.separator + fileName);
+                continue;
+            }
+
+            //tiles文件夹,亚马逊瓦片图
+            if(fileJson.getIntValue("clazz") == 7 ){
+                if(fileName.contains("/4k_")){
+                    continue;
+                }
+                map.put(path + File.separator + "results" + File.separator+ fileName,"images/images"+
+                        projectNum+ File.separator + fileName);
+                continue;
+            }
+
+            //updown文件复制一份到ecs中并去掉换行符
+            if(fileJson.getIntValue("clazz") == 10){
+                String updown = FileUtils.readFile(path + File.separator + "results" +File.separator+ fileName);
+                JSONObject updownJson = JSONObject.parseObject(updown);
+                FileUtils.writeFile(ConstantFilePath.SCENE_PATH + "data" + File.separator + "data" + projectNum +
+                        File.separator + fileName.replace("updown", "mapping"), updownJson.toString());
+                continue;
+            }
+
+            //video视频文件或封面图
+            if(fileJson.getIntValue("clazz") == 11 || fileJson.getIntValue("cl" +
+                    "azz") == 12){
+                map.put(path + File.separator + "results" + File.separator+ fileName,"video/video"+
+                        projectNum+ File.separator + fileName.replace("videos/", ""));
+
+                if(fileName.contains(".mp4")){
+//                    CreateObjUtil.mp4ToFlv(path + File.separator + "results" + File.separator+ fileName,
+//                            path + File.separator + "results" + File.separator+ fileName.replace("mp4", "flv"));
+
+                    map.put(path + File.separator + "results" + File.separator+ fileName.replace("mp4", "flv"),"video/video"+
+                            projectNum+ File.separator + fileName.replace("videos/", "").replace("mp4", "flv"));
+                }
+            }
+
+            //2048的模型和贴图
+            if(fileJson.getIntValue("clazz") == 16){
+                map.put(path + File.separator + "results" + File.separator+ fileName,"data/data"+
+                        projectNum+ File.separator + fileName);
+            }
+
+            if(fileJson.getIntValue("clazz") == 18){
+                map.put(path + File.separator + "results" + File.separator+ fileName,"images/images"+
+                        projectNum+ File.separator + fileName);
+            }
+        }
+
+        CreateObjUtil.convertTxtToDam( path + File.separator + "results" + File.separator+"tex"+File.separator+"modeldata.txt", path + File.separator + "results" +File.separator+ ConstantFileName.modelUUID+"_50k.dam");
+        CreateObjUtil.convertDamToLzma(path + File.separator + "results");
+        CreateObjUtil.convertTxtToDam( path + File.separator + "results" +File.separator+"tex"+File.separator+"modeldata.txt", path + File.separator + "results" + File.separator+ConstantFileName.modelUUID+"_50k.dam");
+        //有meshfix,表示双模型
+        if(!"".equals(meshfix)){
+            CreateObjUtil.convertTxtToDam( path + File.separator + "results" + File.separator+meshfix, path + File.separator + "results" +File.separator+ ConstantFileName.modelUUID+"_50k2.dam");
+            CreateObjUtil.convertDamToLzma2(path + File.separator + "results");
+            CreateObjUtil.convertTxtToDam( path + File.separator + "results" +File.separator+meshfix, path + File.separator + "results" + File.separator+ConstantFileName.modelUUID+"_50k2.dam");
+            map.put(path + File.separator + "results" +File.separator+ConstantFileName.modelUUID+"_50k2.dam.lzma", "images/images"+projectNum+"/"+ConstantFileName.modelUUID+"_50k2.dam.lzma");
+            map.put(path + File.separator + "results" +File.separator+ConstantFileName.modelUUID+"_50k2.dam", "images/images"+projectNum+"/"+ConstantFileName.modelUUID+"_50k2.dam");
+        }
+        //8目相机有两个vision.txt因此第二个叫vision2.txt
+        CreateObjUtil.convertTxtToVisionmodeldata(path + File.separator + "results" +File.separator+"vision.txt",path + File.separator + "results" +File.separator+"vision.modeldata");
+        if(vision2){
+            CreateObjUtil.convertTxtToVisionmodeldata(path + File.separator + "results" +File.separator+"vision2.txt",path + File.separator + "results" +File.separator+"vision2.modeldata");
+            map.put(path + File.separator + "results" +File.separator+"vision2.modeldata", "images/images"+projectNum+"/"+"vision2.modeldata");
+        }else {
+            CreateObjUtil.convertTxtToVisionmodeldataCommon(path + File.separator + "results" +File.separator+"vision.txt",path + File.separator + "results" +File.separator+"vision.modeldata");
+        }
+        log.info("数据转换完成:"+projectNum);
+
+        File file = new File(path + File.separator + "results" +File.separator+ConstantFileName.modelUUID+"_50k.dam.lzma");
+        while(!file.exists())
+        {
+            Thread.sleep(60000);
+        }
+
+        map.put(path + File.separator + "results" +File.separator+"vision.modeldata", "images/images"+projectNum+"/"+"vision.modeldata");
+        map.put(path + File.separator + "results" +File.separator+ConstantFileName.modelUUID+"_50k.dam.lzma", "images/images"+projectNum+"/"+ConstantFileName.modelUUID+"_50k.dam.lzma");
+        map.put(path + File.separator + "results" +File.separator+ConstantFileName.modelUUID+"_50k.dam", "images/images"+projectNum+"/"+ConstantFileName.modelUUID+"_50k.dam");
+
+        file = new File(ConstantFilePath.SCENE_PATH+"data"+File.separator+"data"+projectNum);
+        if(!file.exists())
+        {
+            file.mkdir();
+        }
+        FileUtils.copyFile(path + File.separator + "results" +File.separator+"floor.json", ConstantFilePath.SCENE_PATH+"data"+File.separator+"data"+projectNum+File.separator+"floor.json", true);
+        FileUtils.copyFile(path + File.separator + "results" +File.separator+"floorplan.json", ConstantFilePath.SCENE_PATH+"data"+File.separator+"data"+projectNum+File.separator+"floor.json", true);
+        FileUtils.copyFile(path + File.separator + "results" +File.separator+"floorplan.json", ConstantFilePath.SCENE_PATH+"data"+File.separator+"data"+projectNum+File.separator+"floorplan.json", true);
+        log.info("floor.json路径:"+ path + File.separator + "results" +File.separator+"floor.json");
+        map.put(path + File.separator + "results" +File.separator+"floor.json","data/data"+projectNum+"/floor.json");
+        map.put(path + File.separator + "results" +File.separator+"floorplan.json","data/data"+projectNum+"/floor.json");
+//        map.put(path + File.separator + "results" +File.separator+"floorplan_cad.json","data/data"+projectNum+"/house_floor.json");
+        map.put(path + File.separator + "results" +File.separator+"floorplan_cad.json","data/data"+projectNum+"/floorplan_cad.json");
+        log.info("准备上传文件到oss:"+projectNum);
+        return map;
+    }
+
+
+    public static Map<String,String> computerRebuildVideo(String projectNum, String path) throws Exception{
+        Map<String,String> map = new HashMap<String,String>();
+        path = path.replace("//", "/");
+
+        log.info("开始建模:"+projectNum);
+        //构建算法isModel去掉,因此改成空字符串
+        CreateObjUtil.build3dModel(path, "");
+        log.info("建模完成转换数据:"+projectNum);
+
+        boolean vision2 = false;
+        //读取upload文件,检验需要上传的文件是否存在
+        String uploadData = FileUtils.readFile(path + File.separator + "results" +File.separator+"upload.json");
+        JSONObject uploadJson = null;
+        JSONArray array = null;
+        if(uploadData!=null) {
+            uploadJson = JSONObject.parseObject(uploadData);
+            array = uploadJson.getJSONArray("upload");
+        }
+
+        if(array == null){
+            String instanceId = FileUtils.readFile("/opt/hosts/hosts.txt");
+            FileUtils.writeFile(path + File.separator + "javaErrorNow.log", instanceId + ":计算错误!");
+
+            Thread.sleep(10000L);
+            FileUtils.writeFile(path + File.separator + "javaError.log", instanceId + ":计算错误!");
+            throw new Exception("upload.json数据出错");
+        }
+
+        JSONObject fileJson = null;
+        String fileName = "";
+        for(int i = 0, len = array.size(); i < len; i++) {
+            fileJson = array.getJSONObject(i);
+            fileName = fileJson.getString("file");
+            //文件不存在抛出异常
+            if (!new File(path + File.separator + "results" + File.separator + fileName).exists()) {
+                throw new Exception(path + File.separator + "results" + File.separator + fileName + "文件不存在");
+            }
+
+            //video视频文件或封面图
+            if (fileJson.getIntValue("clazz") == 20) {
+                if (fileName.contains(".flv")) {
+                    map.put(path + File.separator + "results" + File.separator + fileName, "video/video" +
+                            projectNum + File.separator + fileName.replace("videos/", ""));
+                }
+
+                if (fileName.contains(".mp4")) {
+                    map.put(path + File.separator + "results" + File.separator + fileName, "video/video" +
+                            projectNum + File.separator + fileName.replace("videos/", ""));
+                }
+            }
+        }
+
+        log.info("准备上传文件到oss:"+projectNum);
+        return map;
+    }
+
+    /**
+     *  标定算法
+     * @param path
+     * @throws Exception
+     */
+    public static Map<String,String> computerCalibration(String path) throws Exception{
+
+        Map<String,String> map = new HashMap<String,String>();
+
+        log.info("开始标定:" );
+        //构建算法isModel去掉,因此改成空字符串
+        CreateObjUtil.build3dModel(path, "");
+//        CreateObjUtil.build3dModel(unicode, "");
+        log.info("标定完成转换数据:" );
+
+        boolean vision2 = false;
+        //读取upload文件,检验需要上传的文件是否存在
+        String uploadData = FileUtils.readFile(path + File.separator + "results" +File.separator+"upload.json");
+        JSONObject uploadJson = null;
+        JSONArray array = null;
+        if(uploadData!=null) {
+            uploadJson = JSONObject.parseObject(uploadData);
+            array = uploadJson.getJSONArray("upload");
+        }
+        if(array == null){
+            throw new Exception("upload.json数据出错");
+        }
+        JSONObject fileJson = null;
+        String fileName = "";
+        for(int i = 0, len = array.size(); i < len; i++) {
+            fileJson = array.getJSONObject(i);
+            fileName = fileJson.getString("file");
+            //文件不存在抛出异常
+            if (!new File(path + File.separator + "results" + File.separator + fileName).exists()) {
+                throw new Exception(path + File.separator + "results" + File.separator + fileName + "文件不存在");
+            }
+
+            if(fileJson.getIntValue("clazz") == 13 || fileJson.getIntValue("clazz") == 14){
+                map.put(path + File.separator + "results" +File.separator+ fileName,
+                        ConstantFilePath.OSS_PREFIX + path.replace(ConstantFilePath.BUILD_MODEL_PATH, "") +
+                                File.separator + fileName);
+            }
+        }
+        return map;
+    }
+//
+    public static void createJson(String path, String splitType, String skyboxType, String dataDescribe,
+                                  String sceneNum, String dataSource) throws Exception{
+        JSONObject projectJson = new JSONObject();
+        projectJson.put("version", "201909231830");
+        projectJson.put("protocol", "file api 1.4");
+        projectJson.put("uuid", UUID.randomUUID().toString());
+        projectJson.put("description", "");
+        projectJson.put("time", System.currentTimeMillis());
+        projectJson.put("category", "default");
+        projectJson.put("tag", null);
+        projectJson.put("status", null);
+        projectJson.put("sceneNum", sceneNum);
+        projectJson.put("dataSource", dataSource);
+        FileUtils.writeFile(path + File.separator + "project.json", projectJson.toString());
+
+        JSONObject dataJson = new JSONObject();
+        dataJson.put("split_type", splitType);
+        dataJson.put("skybox_type", skyboxType);
+        dataJson.put("extras", null);
+        FileUtils.writeFile(path + File.separator + "data.json", dataJson.toString());
+    }
+
+    public static void createExtras(String rebuildParam, String hdrParam, String path) throws Exception {
+
+        FileUtils.writeFile( path + File.separator + "extras" + File.separator + "videos_hdr_param.json", hdrParam);
+
+        FileUtils.writeFile( path + File.separator + "extras" + File.separator + "required_videos.json", rebuildParam);
+
+    }
+
+    public static void createExtras(String rebuildParam,String path) throws Exception {
+        FileUtils.writeFile( path + File.separator + "extras" + File.separator + "image-ROI.json", rebuildParam);
+    }
+
+    /**
+     * 生成标定数据
+     * @param calPath
+     * @param prefix
+     * @throws Exception
+     */
+    public static void createCalibrationData(String calPath, String prefix) throws Exception{
+        File calFile = new File(calPath);
+        if(calFile.exists()){
+            calFile.mkdirs();
+        }
+        //删除results和capture文件夹
+        FileUtils.deleteDirectory(calPath + "/capture");
+        FileUtils.deleteDirectory(calPath + "/results");
+
+//        CreateObjUtil.ossUtilCp(ConstantFilePath.OSS_PREFIX + prefix, calPath + "/capture");
+        for(File oldFile : new File(prefix).listFiles()){
+            FileUtils.copyFile(oldFile.getAbsolutePath(), calPath + "/capture/" + oldFile.getName(), true);
+        }
+        JSONObject dataJson = new JSONObject();
+        dataJson.put("split_type", "SPLIT_V7");
+        dataJson.put("skybox_type", "SKYBOX_V5");
+        FileUtils.writeFile(calPath + "/data.json", dataJson.toString());
+    }
+
+    public static Map<String, String> getTypeString(String cameraType, String algorithm, String resolution){
+        Map<String, String> map = new HashMap<String, String>();
+        String splitType = "";
+        String skyboxType = "";
+        String dataDescribe = "";
+        if(Integer.parseInt(cameraType) >= 4){
+            if("0".equals(resolution)){
+//            skyboxType = "SKYBOX_V4";  //tiles
+//            skyboxType = "SKYBOX_V6";    //high,low,4k
+                skyboxType = "SKYBOX_V7";    //high,low,2k
+            }else {
+                skyboxType = "SKYBOX_V1";
+            }
+            splitType = "SPLIT_V1";
+//            skyboxType = "SKYBOX_V4";  //tiles
+            dataDescribe = "double spherical";
+
+            if(Integer.parseInt(cameraType) == 5 ){
+                //新双目相机
+//              skyboxType = "SKYBOX_V9";
+                splitType = "SPLIT_V9";
+                skyboxType = "SKYBOX_V1";
+            }
+            if(Integer.parseInt(cameraType) == 6){
+                //小红屋新双目相机
+//                    skyboxType = "SKYBOX_V9";
+                splitType = "SPLIT_V3";
+                skyboxType = "SKYBOX_V7";
+            }
+
+            if(Integer.parseInt(cameraType) == 13){
+                //转台相机
+                skyboxType = "SKYBOX_V6";
+                splitType = "SPLIT_V12";
+            }
+
+            if(Integer.parseInt(cameraType) == 14){
+                //转台相机
+                log.info("激光转台相机调用算法");
+                skyboxType = "SKYBOX_V11";
+                splitType = "SPLIT_V14";
+            }
+
+        }else {
+            if("sfm".equals(algorithm)){
+                splitType = "SPLIT_V2";
+                skyboxType = "SKYBOX_V1";
+                dataDescribe = "old sfm";
+            }else {
+                splitType = "SPLIT_V3";
+                skyboxType = "SKYBOX_V1";
+                dataDescribe = "old slam";
+            }
+        }
+        map.put("splitType", splitType);
+        map.put("skyboxType", skyboxType);
+        map.put("dataDescribe", dataDescribe);
+        return map;
+    }
+
+//    public static SceneEntity createScene(String projectNum, Long cameraId, String cameraName, String phoneId, String scenepsd,
+//                                          String unicode, Long cameraType, String fileId, String prefix,
+//                                          String imgsName, String pic, String isModel, Long userId, String userName,
+//                                          String algorithm, Integer sceneShootCount, String sceneName,
+//                                          String sceneDec, Integer sceneType, String gps, ISceneService sceneService,
+//                                          Integer type, ModelingMsgProducer producer, String url, String ecsType,
+//                                          RubberSheetingUtil rubberSheetingUtil)throws Exception{
+//        //先返回链接地址
+//        SceneEntity scene = new SceneEntity();
+//        scene.setWebSite(url+projectNum);
+//        scene.setCameraId(cameraId);
+//        scene.setPhoneId(phoneId);
+//        scene.setNum(String.valueOf(projectNum));
+//        if(scenepsd == null)
+//        {
+//            scenepsd = "";
+//        }
+//        if(!scenepsd.equals(""))
+//        {
+//            scene.setSceneKey(scenepsd);
+//        }
+//
+//        if(!StringUtils.isEmpty(ecsType)){
+//            scene.setEcs(ecsType);
+//        }
+//
+//        String path =  ConstantFilePath.BUILD_MODEL_PATH + unicode;
+//
+//        if(cameraType.longValue() >= 4){
+//            scene.setDataSource(ConstantFilePath.BUILD_MODEL_PATH +
+//                    cameraName.replace("4DKKPRO_", "").replace("-fdage", "").toLowerCase() + File.separator + fileId + File.separator + unicode);
+//        }else {
+//            scene.setDataSource(prefix+imgsName);
+//        }
+//
+//        if(cameraType.longValue() == 14){
+//
+//            scene.setDataSource(ConstantFilePath.BUILD_MODEL_LASER_PATH +
+//                    cameraName.replace("4DKKPRO_", "").replace("-fdage", "").toLowerCase() + File.separator +
+//                    fileId + File.separator + unicode);
+//
+//            log.info("激光相机 dataSource :" + scene.getDataSource());
+//
+//        }
+//
+//
+//        if(pic!=null&&pic.length()>5)
+//        {
+//            scene.setThumb(pic);
+//        }
+//        else
+//        {
+//            scene.setThumb(ConstantUrl.DEFAULT_SCENE_PIC);
+//        }
+//
+//        String parametr = "";
+//        parametr+=unicode+":;"+path+":;"+prefix+":;"+imgsName+":;"+projectNum+":;"+isModel;
+//        if(userName!=null&&!userName.trim().equals(""))
+//        {
+//            parametr+=":;"+userName;
+//            scene.setUserId(userId);
+//        }
+//        else
+//        {
+//            parametr+=":;noMan";
+//        }
+//        parametr+=":;"+cameraType;
+//        parametr+=":;"+algorithm;
+//        parametr += ":;" + fileId;
+//        parametr += ":;" + cameraName;
+//        parametr += ":;1";
+//        log.info("大场景添加到队列:"+parametr);
+//        producer.sendMsg(parametr);
+//
+//        if(sceneShootCount == null)
+//        {
+//            scene.setShootCount(0);
+//        }
+//        else
+//        {
+//            scene.setShootCount(sceneShootCount);
+//        }
+//        if(sceneName!=null)
+//        {
+//            scene.setSceneName(sceneName);
+//        }
+//        if(sceneDec!=null)
+//        {
+//            scene.setSceneDec("<p>"+sceneDec+"</p>");
+//        }
+//
+//        if(sceneType!=null)
+//        {
+//            scene.setSceneType(sceneType);
+//        }
+//
+//        if(gps!=null&&!gps.trim().equals(""))
+//        {
+//            scene.setGps(gps);
+//        }
+//
+//        scene.setSceneScheme(cameraType.intValue());
+//        scene.setAlgorithm(algorithm);
+//        log.info("场景记录添加到数据库:"+projectNum);
+//        if(type == 0){
+//            sceneService.save(scene);
+//        }
+//
+//        JSONObject scenejson = JSONObject.parseObject(JSONObject.toJSONString(scene));
+//        scenejson.put("thumbImg", 0);
+//        scenejson.put("version", 0);
+//        scenejson.put("floorLogo", 0);
+//        if(!scenepsd.equals("")){
+//            scenejson.put("scenePsd", scenepsd);
+//            scenejson.put("public", 1);
+//        }else{
+//            scenejson.put("scenePsd", "");
+//            scenejson.put("public", 0);
+//        }
+//        if(cameraType < 4){
+//            scenejson.put("visions", 1);
+//        }else {
+//            scenejson.put("visions", 2);
+//        }
+//        scenejson.put("createTime", new DateTime(new Date()).toString("yyyy-MM-dd HH:mm"));
+//
+//        File file = new File(ConstantFilePath.SCENE_PATH+"data/data"+projectNum);
+//        if(!file.exists()||!file.isDirectory())
+//        {
+//            file.mkdirs();
+//        }
+//        FileUtils.writeFile(ConstantFilePath.SCENE_PATH+"data/data"+projectNum+File.separator+"scene.json", scenejson.toString());
+//
+//        //生成二维码
+//        MatrixToImageWriterUtil.createQRCode(url + projectNum, ConstantFilePath.BASE_PATH + File.separator + "sceneQRcode/"+projectNum+".png", null);
+//        MatrixToImageWriterUtil.createQRCode(url + projectNum + "&lang=en", ConstantFilePath.BASE_PATH + File.separator + "sceneQRcode/"+projectNum+"_en.png", null);
+//        log.info("二维码生成完成");
+//
+//        return scene;
+//    }
+
+
+    public static String getMQMsg(String projectNum, String cameraName, String unicode, Long cameraType, String fileId,
+                                  String prefix, String imgsName, String isModel,String userName,
+                                  String algorithm, Integer resolution, String buildType, String path) {
+        String parametr = "";
+        parametr+= unicode +":;"+ path +":;"+ prefix +":;"+ imgsName +":;"+ projectNum +":;"+ isModel;
+        if(userName !=null&&!userName.trim().equals("")){
+            parametr+=":;"+ userName;
+        }else{
+            parametr+=":;noMan";
+        }
+        parametr+=":;"+ cameraType;
+        parametr+=":;"+ algorithm;
+        parametr += ":;" + fileId;
+        parametr += ":;" + cameraName;
+        if(resolution == null){
+            parametr += ":;0";
+        }else {
+            parametr += ":;" + resolution.intValue();
+        }
+
+        if(buildType != null){
+            parametr += ":;" + buildType;
+        }
+
+        log.info("pro大场景添加到队列:"+parametr);
+        return parametr;
+    }
+}

+ 1 - 1
4dkankan-common-utils/src/main/java/com/fdkankan/common/utils/ConstantCmd.java

@@ -1,4 +1,4 @@
-package com.fdkankan.common.utils;
+package com.fdkankan.common.util;
 
 public class ConstantCmd {
 

+ 219 - 0
4dkankan-common-utils/src/main/java/com/fdkankan/common/util/ConvertCommonUtils.java

@@ -0,0 +1,219 @@
+package com.fdkankan.common.util;
+
+import com.fdkankan.common.proto.Common;
+import com.fdkankan.common.proto.format.JsonFormat;
+import lombok.extern.slf4j.Slf4j;
+
+import java.io.*;
+import java.util.ArrayList;
+import java.util.List;
+
+@Slf4j
+public class ConvertCommonUtils {
+
+    public static void convertVisionModelDataToTxt(String srcPath, String desPath) throws Exception {
+
+        BufferedOutputStream bos = null;
+        BufferedInputStream bis = null;
+        try {
+            File file = new File(srcPath);
+            FileInputStream fis = new FileInputStream(file);
+
+            Common.NavigationInfo data_NavigationInfo = Common.NavigationInfo.parseFrom(fis);
+
+            String jsonFormat1 = JsonFormat.printToString(data_NavigationInfo);
+            ByteArrayInputStream stream = new ByteArrayInputStream(jsonFormat1.getBytes());
+            bos = new BufferedOutputStream(new FileOutputStream(desPath));//设置输出路径
+            bis = new BufferedInputStream(stream);
+            int b = -1;
+            while ((b = bis.read()) != -1) {
+                bos.write(b);
+            }
+            //out.close();
+            bis.close();
+            bos.close();
+        } catch (Exception e) {
+            StringWriter trace = new StringWriter();
+            e.printStackTrace(new PrintWriter(trace));
+            log.error(trace.toString());
+        } finally {
+            if (bos != null) {
+                bos.close();
+            }
+            if (bis != null) {
+                bis.close();
+            }
+        }
+    }
+
+    public static void convertTxtToVisionModelData(String srcPath, String desPath) throws Exception {
+        BufferedOutputStream bos = null;
+        BufferedInputStream bis = null;
+        try {
+            Common.NavigationInfo.Builder builder = Common.NavigationInfo.newBuilder();
+            String jsonFormat = readTxtFileToJson(srcPath);
+            JsonFormat.merge(jsonFormat, builder);
+            byte[] buf = builder.build().toByteArray();
+
+            //把序列化后的数据写入本地磁盘
+            ByteArrayInputStream stream = new ByteArrayInputStream(buf);
+            bos = new BufferedOutputStream(new FileOutputStream(desPath));//设置输出路径
+            bis = new BufferedInputStream(stream);
+            int b = -1;
+            while ((b = bis.read()) != -1) {
+                bos.write(b);
+            }
+            bis.close();
+            bos.close();
+        } catch (Exception e) {
+            StringWriter trace = new StringWriter();
+            e.printStackTrace(new PrintWriter(trace));
+            log.error(trace.toString());
+        } finally {
+            if (bos != null) {
+                bos.close();
+            }
+            if (bis != null) {
+                bis.close();
+            }
+        }
+    }
+
+    public static String readTxtFileToJson(String filePath) {
+        try {
+            String encoding = "UTF-8";
+            File file = new File(filePath);
+            if (file.isFile() && file.exists()) {
+                InputStreamReader read = new InputStreamReader(
+                        new FileInputStream(file), encoding);
+                BufferedReader bufferedReader = new BufferedReader(read);
+                String lineTxt = null;
+                String result = "";
+                while ((lineTxt = bufferedReader.readLine()) != null) {
+                    result += lineTxt;
+                }
+                read.close();
+                return result;
+            } else {
+                return null;
+            }
+        } catch (Exception e) {
+            e.printStackTrace();
+            return null;
+        }
+    }
+
+
+    public List<List<String>> descartes(List<List<String>> dimValue) {
+        List<List<String>> res = new ArrayList<>();
+        if (dimValue == null || dimValue.size() == 0)
+            return res;
+        backtrace(dimValue, 0, res, new ArrayList<>());
+        return res;
+
+    }
+
+    /**
+     * 递归回溯法求解
+     *
+     * @param dimValue 原始数据集合
+     * @param index 当前执行的集合索引
+     * @param result 结果集合
+     * @param curList 当前的单个结果集
+     */
+    private void backtrace(List<List<String>> dimValue, int index,
+                           List<List<String>> result, List<String> curList) {
+
+        if (curList.size() == dimValue.size())
+            result.add(new ArrayList<>(curList));
+        else
+            for (int j = 0; j < dimValue.get(index).size(); j++) {
+                curList.add(dimValue.get(index).get(j));
+                backtrace(dimValue, index + 1, result, curList);
+                curList.remove(curList.size() - 1);
+            }
+
+    }
+
+    public static void main(String[] args) {
+        List<String> list1 = new ArrayList<String>();
+        list1.add("普通会员");
+        list1.add("专业会员");
+        list1.add("商业会员");
+        List<String> list2 = new ArrayList<String>();
+        list2.add("1G");
+        list2.add("1T");
+        List<List<String>> dimValue = new ArrayList<List<String>>();
+        dimValue.add(list1);
+        dimValue.add(list2);
+
+        // 递归实现笛卡尔积
+        ConvertCommonUtils s = new ConvertCommonUtils();
+        List<List<String>> res = s.descartes(dimValue);
+        System.out.println("递归实现笛卡尔乘积: 共 " + res.size() + " 个结果");
+        for (List<String> list : res) {
+            for (String string : list) {
+                System.out.print(string + " ");
+            }
+            System.out.println();
+        }
+    }
+
+    public static void convertTxtToVisionmodeldata(String srcpath,String despath)throws Exception
+    {
+        try
+        {
+            Common.NavigationInfo.Builder builder = Common.NavigationInfo.newBuilder();
+            String jsonFormat = readTxtFileToJson(srcpath);
+            JsonFormat.merge(jsonFormat, builder);
+            byte[] buf= builder.build().toByteArray();
+
+            //把序列化后的数据写入本地磁盘
+            ByteArrayInputStream stream = new ByteArrayInputStream(buf);
+            BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(despath));//设置输出路径
+            BufferedInputStream bis = new BufferedInputStream(stream);
+            int b = -1;
+            while ((b = bis.read()) != -1) {
+                bos.write(b);
+            }
+            bis.close();
+            bos.close();
+        }
+        catch(Exception e)
+        {
+            StringWriter trace=new StringWriter();
+            e.printStackTrace(new PrintWriter(trace));
+            log.error(trace.toString());
+        }
+    }
+
+    public static void convertVisionmodeldataToTxt(String srcpath,String despath)throws Exception
+    {
+        try
+        {
+            File file = new File(srcpath);
+            FileInputStream fis=new FileInputStream(file);
+
+            Common.NavigationInfo data_NavigationInfo = Common.NavigationInfo.parseFrom(fis);
+
+            //PrintStream out = new PrintStream(despath);
+            String jsonFormat1 = JsonFormat.printToString(data_NavigationInfo);
+            ByteArrayInputStream stream = new ByteArrayInputStream(jsonFormat1.getBytes());
+            BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(despath));//设置输出路径
+            BufferedInputStream bis = new BufferedInputStream(stream);
+            int b = -1;
+            while ((b = bis.read()) != -1) {
+                bos.write(b);
+            }
+            //out.close();
+            bis.close();
+            bos.close();
+        }
+        catch(Exception e)
+        {
+            StringWriter trace=new StringWriter();
+            e.printStackTrace(new PrintWriter(trace));
+            log.error(trace.toString());
+        }
+    }
+}

+ 219 - 0
4dkankan-common-utils/src/main/java/com/fdkankan/common/util/ConvertUtils.java

@@ -0,0 +1,219 @@
+package com.fdkankan.common.util;
+
+import com.fdkankan.common.proto.Visionmodeldata;
+import com.fdkankan.common.proto.format.JsonFormat;
+import lombok.extern.slf4j.Slf4j;
+
+import java.io.*;
+import java.util.ArrayList;
+import java.util.List;
+
+@Slf4j
+public class ConvertUtils {
+
+    public static void convertVisionModelDataToTxt(String srcPath, String desPath) throws Exception {
+
+        BufferedOutputStream bos = null;
+        BufferedInputStream bis = null;
+        try {
+            File file = new File(srcPath);
+            FileInputStream fis = new FileInputStream(file);
+
+            Visionmodeldata.NavigationInfo data_NavigationInfo = Visionmodeldata.NavigationInfo.parseFrom(fis);
+
+            String jsonFormat1 = JsonFormat.printToString(data_NavigationInfo);
+            ByteArrayInputStream stream = new ByteArrayInputStream(jsonFormat1.getBytes());
+            bos = new BufferedOutputStream(new FileOutputStream(desPath));//设置输出路径
+            bis = new BufferedInputStream(stream);
+            int b = -1;
+            while ((b = bis.read()) != -1) {
+                bos.write(b);
+            }
+            //out.close();
+            bis.close();
+            bos.close();
+        } catch (Exception e) {
+            StringWriter trace = new StringWriter();
+            e.printStackTrace(new PrintWriter(trace));
+            log.error(trace.toString());
+        } finally {
+            if (bos != null) {
+                bos.close();
+            }
+            if (bis != null) {
+                bis.close();
+            }
+        }
+    }
+
+    public static void convertTxtToVisionModelData(String srcPath, String desPath) throws Exception {
+        BufferedOutputStream bos = null;
+        BufferedInputStream bis = null;
+        try {
+            Visionmodeldata.NavigationInfo.Builder builder = Visionmodeldata.NavigationInfo.newBuilder();
+            String jsonFormat = readTxtFileToJson(srcPath);
+            JsonFormat.merge(jsonFormat, builder);
+            byte[] buf = builder.build().toByteArray();
+
+            //把序列化后的数据写入本地磁盘
+            ByteArrayInputStream stream = new ByteArrayInputStream(buf);
+            bos = new BufferedOutputStream(new FileOutputStream(desPath));//设置输出路径
+            bis = new BufferedInputStream(stream);
+            int b = -1;
+            while ((b = bis.read()) != -1) {
+                bos.write(b);
+            }
+            bis.close();
+            bos.close();
+        } catch (Exception e) {
+            StringWriter trace = new StringWriter();
+            e.printStackTrace(new PrintWriter(trace));
+            log.error(trace.toString());
+        } finally {
+            if (bos != null) {
+                bos.close();
+            }
+            if (bis != null) {
+                bis.close();
+            }
+        }
+    }
+
+    public static String readTxtFileToJson(String filePath) {
+        try {
+            String encoding = "UTF-8";
+            File file = new File(filePath);
+            if (file.isFile() && file.exists()) {
+                InputStreamReader read = new InputStreamReader(
+                        new FileInputStream(file), encoding);
+                BufferedReader bufferedReader = new BufferedReader(read);
+                String lineTxt = null;
+                String result = "";
+                while ((lineTxt = bufferedReader.readLine()) != null) {
+                    result += lineTxt;
+                }
+                read.close();
+                return result;
+            } else {
+                return null;
+            }
+        } catch (Exception e) {
+            e.printStackTrace();
+            return null;
+        }
+    }
+
+
+    public List<List<String>> descartes(List<List<String>> dimValue) {
+        List<List<String>> res = new ArrayList<>();
+        if (dimValue == null || dimValue.size() == 0)
+            return res;
+        backtrace(dimValue, 0, res, new ArrayList<>());
+        return res;
+
+    }
+
+    /**
+     * 递归回溯法求解
+     *
+     * @param dimValue 原始数据集合
+     * @param index 当前执行的集合索引
+     * @param result 结果集合
+     * @param curList 当前的单个结果集
+     */
+    private void backtrace(List<List<String>> dimValue, int index,
+                           List<List<String>> result, List<String> curList) {
+
+        if (curList.size() == dimValue.size())
+            result.add(new ArrayList<>(curList));
+        else
+            for (int j = 0; j < dimValue.get(index).size(); j++) {
+                curList.add(dimValue.get(index).get(j));
+                backtrace(dimValue, index + 1, result, curList);
+                curList.remove(curList.size() - 1);
+            }
+
+    }
+
+    public static void main(String[] args) {
+        List<String> list1 = new ArrayList<String>();
+        list1.add("普通会员");
+        list1.add("专业会员");
+        list1.add("商业会员");
+        List<String> list2 = new ArrayList<String>();
+        list2.add("1G");
+        list2.add("1T");
+        List<List<String>> dimValue = new ArrayList<List<String>>();
+        dimValue.add(list1);
+        dimValue.add(list2);
+
+        // 递归实现笛卡尔积
+        ConvertUtils s = new ConvertUtils();
+        List<List<String>> res = s.descartes(dimValue);
+        System.out.println("递归实现笛卡尔乘积: 共 " + res.size() + " 个结果");
+        for (List<String> list : res) {
+            for (String string : list) {
+                System.out.print(string + " ");
+            }
+            System.out.println();
+        }
+    }
+
+    public static void convertTxtToVisionmodeldata(String srcpath,String despath)throws Exception
+    {
+        try
+        {
+            Visionmodeldata.NavigationInfo.Builder builder = Visionmodeldata.NavigationInfo.newBuilder();
+            String jsonFormat = readTxtFileToJson(srcpath);
+            JsonFormat.merge(jsonFormat, builder);
+            byte[] buf= builder.build().toByteArray();
+
+            //把序列化后的数据写入本地磁盘
+            ByteArrayInputStream stream = new ByteArrayInputStream(buf);
+            BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(despath));//设置输出路径
+            BufferedInputStream bis = new BufferedInputStream(stream);
+            int b = -1;
+            while ((b = bis.read()) != -1) {
+                bos.write(b);
+            }
+            bis.close();
+            bos.close();
+        }
+        catch(Exception e)
+        {
+            StringWriter trace=new StringWriter();
+            e.printStackTrace(new PrintWriter(trace));
+            log.error(trace.toString());
+        }
+    }
+
+    public static void convertVisionmodeldataToTxt(String srcpath,String despath)throws Exception
+    {
+        try
+        {
+            File file = new File(srcpath);
+            FileInputStream fis=new FileInputStream(file);
+
+            Visionmodeldata.NavigationInfo data_NavigationInfo = Visionmodeldata.NavigationInfo.parseFrom(fis);
+
+            //PrintStream out = new PrintStream(despath);
+            String jsonFormat1 = JsonFormat.printToString(data_NavigationInfo);
+            ByteArrayInputStream stream = new ByteArrayInputStream(jsonFormat1.getBytes());
+            BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(despath));//设置输出路径
+            BufferedInputStream bis = new BufferedInputStream(stream);
+            int b = -1;
+            while ((b = bis.read()) != -1) {
+                bos.write(b);
+            }
+            //out.close();
+            bis.close();
+            bos.close();
+        }
+        catch(Exception e)
+        {
+            StringWriter trace=new StringWriter();
+            e.printStackTrace(new PrintWriter(trace));
+            log.error(trace.toString());
+        }
+    }
+}

+ 1 - 1
4dkankan-common-utils/src/main/java/com/fdkankan/common/utils/CreateObjUtil.java

@@ -1,4 +1,4 @@
-package com.fdkankan.common.utils;
+package com.fdkankan.common.util;
 
 import com.fdkankan.common.constant.ConstantFileName;
 import com.fdkankan.common.constant.ConstantFilePath;

+ 1 - 1
4dkankan-common-utils/src/main/java/com/fdkankan/common/utils/DataUtils.java

@@ -1,4 +1,4 @@
-package com.fdkankan.common.utils;
+package com.fdkankan.common.util;
 
 import cn.hutool.core.util.StrUtil;
 import org.springframework.stereotype.Component;

+ 46 - 0
4dkankan-common-utils/src/main/java/com/fdkankan/common/util/DateEditor.java

@@ -0,0 +1,46 @@
+package com.fdkankan.common.util;
+
+import org.apache.commons.lang3.time.DateUtils;
+
+import java.beans.PropertyEditorSupport;
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+
+public class DateEditor extends PropertyEditorSupport {
+
+    private boolean emptyAsNull;
+    private String dateFormat = "yyyy-MM-dd HH:mm:ss";
+    public static final String[] DATE_PATTERNS = {"yyyy", "yyyy-MM", "yyyyMM", "yyyy/MM", "yyyy-MM-dd", "yyyyMMdd",
+            "yyyy/MM/dd", "yyyy-MM-dd HH:mm:ss", "yyyyMMddHHmmss", "yyyy/MM/dd HH:mm:ss"};
+
+    public DateEditor(boolean emptyAsNull) {
+        this.emptyAsNull = emptyAsNull;
+    }
+
+    public DateEditor(boolean emptyAsNull, String dateFormat) {
+        this.emptyAsNull = emptyAsNull;
+        this.dateFormat = dateFormat;
+    }
+
+    public String getAsText() {
+        Date date = (Date) getValue();
+        return date != null ? new SimpleDateFormat(this.dateFormat).format(date) : "";
+    }
+
+    public void setAsText(String text) {
+        if (text == null) {
+            setValue(null);
+        } else {
+            String str = text.trim();
+            if ((this.emptyAsNull) && ("".equals(str)))
+                setValue(null);
+            else
+                try {
+                    setValue(DateUtils.parseDate(str, DATE_PATTERNS));
+                } catch (ParseException e) {
+                    setValue(null);
+                }
+        }
+    }
+}

+ 33 - 0
4dkankan-common-utils/src/main/java/com/fdkankan/common/util/DateExtUtil.java

@@ -0,0 +1,33 @@
+package com.fdkankan.common.util;
+
+import java.util.Date;
+import java.util.GregorianCalendar;
+
+public class DateExtUtil {
+
+    public static final String dateStyle = "yyyy-MM-dd HH:mm:ss";
+    public static final String dateStyle2 = "HH:mm:ss";
+    public static final String dateStyle3 = "HH:mm";
+    public static final String dateStyle4 = "yyyy-MM-dd";
+    public static final String dateStyle5 = "yyyy-MM";
+    public static final String dateStyle6 = "yyyyMMdd";
+    public static final String dateStyle7 = "yyMMddHHmm";
+    public static final String dateStyle8 = "yyyy-MM-dd HH:mm";
+    public static final String dateStyle9 = "yyyy.MM.dd";
+
+    public static Date hoursCalculate(Date beginDate, int hours) {
+        return timesCalculate(beginDate, hours, GregorianCalendar.HOUR);
+    }
+
+    public static Date timesCalculate(Date beginDate, int times, int type) {
+        /*
+         * GregorianCalendar类的add(int field,int amount)方法表示年月日加减.
+         * field参数表示年,月,周,日等. amount参数表示要加减的数量.
+         */
+        GregorianCalendar gc = new GregorianCalendar();
+        gc.setTime(beginDate);
+        gc.add(type, times);
+        return gc.getTime();
+    }
+
+}

+ 411 - 0
4dkankan-common-utils/src/main/java/com/fdkankan/common/util/DateUtil.java

@@ -0,0 +1,411 @@
+package com.fdkankan.common.util;
+
+import lombok.extern.slf4j.Slf4j;
+
+import java.text.DateFormat;
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.util.*;
+
+@Slf4j
+public final class DateUtil {
+
+    /**
+     * 时间格式
+     */
+    public static final String DEFAULT_DATE_FORMAT = "yyyy-MM-dd HH:mm:ss";
+
+    public static final String YYYY_MM_DD_DATE_FORMAT = "yyyy-MM-dd";
+
+    public static final String YYYYMMDD_DATA_FORMAT = "yyyyMMdd";
+
+    public static final String HHMMSS_DATA_FORMAT = "HHmmss";
+
+    public static final String YYYYMMDDHHMMSSSSS_DATA_FORMAT = "yyyyMMddHHmmssSSS";
+
+    public static final String YYYYMMDDHHMMSS_DATA_FORMAT = "yyyyMMddHHmmss";
+
+    public static final String YYMMDDHHMMSS_DATA_FORMAT = "yyMMddHHmmss";
+
+    public static final String YYMMDDHHMM_DATA_FORMAT = "yyyyMMddHHmm";
+
+
+    /**
+     * 过去的Date对象,TIMESTAMP值可以从1970的某时的开始一直到2037年
+     */
+    public static final Date PASSED_DATE = DateUtil.string2Date("2000-01-01 00:00:00",
+            DEFAULT_DATE_FORMAT);;
+    /**
+     * 永久的Date对象,TIMESTAMP值可以从1970的某时的开始一直到2037年
+     */
+    public static final Date FOREVER_DATE = DateUtil.string2Date("9999-12-31 23:59:59",
+            DEFAULT_DATE_FORMAT);
+
+    private DateUtil() {
+    }
+
+    /**
+     * 把时间转成北京时间的时间戳
+     *
+     * @param input
+     * @return
+     */
+    public static long convert2CST(String input) {
+        SimpleDateFormat dff = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
+        dff.setTimeZone(TimeZone.getTimeZone("GMT+08"));
+
+        long result = -1;
+        try {
+            Date cstDate = dff.parse(input);
+            result = cstDate.getTime();
+        } catch (Exception e) {
+            log.error("convert2CST meet exception.", e);
+        }
+
+        return result;
+    }
+
+    /**
+     * 把时间戳转成北京时间的字符串表示
+     *
+     * @param input
+     * @return
+     */
+    public static String convert2CST(long input) {
+        SimpleDateFormat dff = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
+        dff.setTimeZone(TimeZone.getTimeZone("GMT+08"));
+
+        try {
+            return dff.format(new Date(input));
+        } catch (Exception e) {
+            log.error("convert2CST meet exception.", e);
+        }
+
+        return "";
+    }
+
+
+    /**
+     * 判断两个日期是否是同一天
+     *
+     * @param dateA
+     *            日期1
+     * @param dateB
+     *            日期2
+     * @return true:false
+     */
+    public static boolean isSameDay(Date dateA, Date dateB) {
+        Calendar calDateA = Calendar.getInstance();
+        calDateA.setTime(dateA);
+
+        Calendar calDateB = Calendar.getInstance();
+        calDateB.setTime(dateB);
+
+        return calDateA.get(Calendar.YEAR) == calDateB.get(Calendar.YEAR)
+                && calDateA.get(Calendar.MONTH) == calDateB.get(Calendar.MONTH)
+                && calDateA.get(Calendar.DAY_OF_MONTH) == calDateB.get(Calendar.DAY_OF_MONTH);
+    }
+
+    /**
+     * 将Java日期转成以秒为单位,去除毫秒信息
+     * java中Date类中的getTime()是获取时间戳的,java中生成的时间戳精确到毫秒级别,而unix中精确到秒级别,
+     * 所以通过java生成的时间戳需要除以1000
+     *
+     * @param date
+     * @return
+     */
+    public static Date truncMesc(Date date) {
+        String strDate = DateUtil.date2String(date, DEFAULT_DATE_FORMAT);
+
+        Date result = null;
+        try {
+            SimpleDateFormat dateFmt = new SimpleDateFormat(DEFAULT_DATE_FORMAT);
+            result = dateFmt.parse(strDate);
+        } catch (Exception e) {
+            log.error("truncMesc meet exception", e);
+        }
+
+        return result;
+    }
+
+    /**
+     * 判断当前时间是否在指定的有效期内
+     *
+     * @param beginDate
+     *            开始时间
+     * @param endDate
+     *            结束时间
+     * @return true : false
+     */
+    public static boolean isInPeriod(Date beginDate, Date endDate) {
+        Date now = new Date();
+
+        if (beginDate == null || endDate == null) {
+            log.error("isInPeriod meet null argument.");
+            throw new IllegalArgumentException("isInPeriod meet null argument.");
+        }
+
+        if (beginDate.before(endDate) == false) {
+            log.error("isInPeriod meet invalid date argument.");
+            throw new IllegalArgumentException("isInPeriod meet invalid date argument.");
+        }
+
+        if (now.after(beginDate) && now.before(endDate)) {
+            return true;
+        } else {
+            return false;
+        }
+    }
+
+    /**
+     * 判断目标时间是否比当前时间早
+     *
+     * @param targetDate
+     *            需比较的时间
+     * @return
+     */
+    public static boolean isBeforeNow(Date targetDate) {
+        if (targetDate == null) {
+            log.error("isBeforeNow meet null argument.");
+            throw new IllegalArgumentException("isBeforeNow meet null argument.");
+        }
+
+        Date now = new Date();
+
+        return (now.after(targetDate)) ? true : false;
+    }
+
+    /**
+     * 判断目标时间是否比当前时间早
+     *
+     * @param targetDate
+     *            需比较的时间
+     * @return
+     */
+    public static boolean isBeforeNow2(Date targetDate) {
+        if (targetDate == null) {
+            log.error("isBeforeNow meet null argument.");
+            throw new IllegalArgumentException("isBeforeNow meet null argument.");
+        }
+
+        Date now = new Date();
+
+        return (now.after(targetDate)) ? false : true;
+    }
+
+    /**
+     * @param beginDate
+     *            开始时期
+     * @param days
+     *            偏离天数,> 0 往后推算; < 0 往前推算
+     * @return
+     */
+    public static Date daysCalculate(Date beginDate, int days) {
+        return timesCalculate(beginDate, days, GregorianCalendar.DATE);
+    }
+
+    /**
+     * @param beginDate
+     *            开始时期
+     * @return
+     */
+    public static Date hoursCalculate(Date beginDate, int hours) {
+        return timesCalculate(beginDate, hours, GregorianCalendar.HOUR);
+    }
+
+    public static Date timesCalculate(Date beginDate, int times, int type) {
+        /*
+         * GregorianCalendar类的add(int field,int amount)方法表示年月日加减.
+         * field参数表示年,月,周,日等. amount参数表示要加减的数量.
+         */
+        GregorianCalendar gc = new GregorianCalendar();
+        gc.setTime(beginDate);
+        gc.add(type, times);
+        return gc.getTime();
+    }
+
+    /**
+     * 将日期对象按照格式转成字符串
+     *
+     * @param date
+     *            日期对象
+     * @param format
+     *            日期格式
+     * @return 字符串
+     */
+    public static String date2String(Date date, String format) {
+        if (date == null) {
+            log.error("date2String meet null argument.");
+            throw new IllegalArgumentException("argument is null.");
+        }
+
+        if (format == null) {
+            format = DEFAULT_DATE_FORMAT;
+        }
+
+        String result = null;
+        try {
+            DateFormat fmt = new SimpleDateFormat(format);
+            result = fmt.format(date);
+        } catch (Exception e) {
+            log.error("date2String meet exception. " + e.getLocalizedMessage());
+        }
+        return result;
+    }
+
+    /**
+     * 将字符串转成日期对象
+     *
+     * @param date
+     *            日期字符串
+     * @param format
+     *            日期格式
+     * @return 日期对象
+     */
+    public static Date string2Date(String date, String format) {
+        if (date == null) {
+            log.error("string2Date meet null argument.");
+            throw new IllegalArgumentException("argument is null.");
+        }
+
+        if (format == null) {
+            format = DEFAULT_DATE_FORMAT;
+        }
+
+        Date result = null;
+        try {
+            DateFormat fmt = new SimpleDateFormat(format);
+            result = fmt.parse(date);
+        } catch (Exception e) {
+            log.error("string2Date meet exception. " + e.getLocalizedMessage());
+        }
+
+        return result;
+    }
+
+    /**
+     * java时间戳转换到php时间戳
+     *
+     * @param time
+     * @return
+     */
+    public static long javaTimestamp(long time) {
+        if (time <= 0) {
+            log.error("javaTimestamp meet null argument.");
+            throw new IllegalArgumentException("argument is null.");
+        }
+        // mysql 时间戳只有10位,只精确到秒,而Java时间戳精确到毫秒,故要做处理
+        String dateline = String.valueOf(time);
+        dateline = dateline.substring(0, 10);
+        return Long.parseLong(dateline);
+    }
+
+    public static long javaTimestamp(Date now) {
+        return javaTimestamp(now.getTime());
+    }
+
+    /**
+     * 计算两个日期之间相差的天数
+     *
+     * @param smdate
+     *            较小的时间
+     * @param bdate
+     *            较大的时间
+     * @return 相差天数
+     * @throws ParseException
+     */
+    public static int daysBetween(Date smdate, Date bdate) {
+        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
+        try {
+            smdate = sdf.parse(sdf.format(smdate));
+            bdate = sdf.parse(sdf.format(bdate));
+        } catch (ParseException e) {
+            log.error("ParseException:", e);
+        }
+        Calendar cal = Calendar.getInstance();
+        cal.setTime(smdate);
+        long time1 = cal.getTimeInMillis();
+        cal.setTime(bdate);
+        long time2 = cal.getTimeInMillis();
+        long between_days = (time2 - time1) / (1000 * 3600 * 24);
+
+        return Integer.parseInt(String.valueOf(between_days));
+    }
+
+    /**
+     * 调整日期
+     * @param date
+     * @param num
+     * @param type calendar.DATE
+     * @return 相差天数
+     * @throws ParseException
+     */
+    public static Date delay(Date date,int num, int type) {
+        Calendar calendar = new GregorianCalendar();
+        calendar.setTime(date);
+        calendar.add(type, num);// 把日期往后增加一天.整数往后推,负数往前移动
+        date = calendar.getTime(); // 这个时间就是日期往后推一天的结果
+        return date;
+    }
+
+    /**
+     * 获取某年某月的最后一天日期
+     */
+    public static Date getLastDayOfMonth(int year, int month) {
+        Calendar cal = Calendar.getInstance();
+        cal.set(Calendar.YEAR, year);
+        cal.set(Calendar.MONTH, month - 1);
+        int lastDay = cal.getActualMaximum(Calendar.DAY_OF_MONTH);
+        cal.set(Calendar.DAY_OF_MONTH, lastDay);
+        return cal.getTime();
+    }
+
+    /**
+     * 获取某年某月的第一天 日期
+     */
+    public static Date getFisrtDayOfMonth(int year, int month) {
+        Calendar cal = Calendar.getInstance();
+        cal.set(Calendar.YEAR, year);
+        cal.set(Calendar.MONTH, month - 1);
+        int firstDay = cal.getActualMinimum(Calendar.DAY_OF_MONTH);
+        cal.set(Calendar.DAY_OF_MONTH, firstDay);
+        return cal.getTime();
+    }
+
+    /**
+     * 根据开始时间和结束时间返回时间段内的时间集合
+     *
+     * @param beginDate
+     * @param endDate
+     * int calendarType 差距的时间 如获取间隔为一天 输入Calendar.DAY_OF_MONTH
+     * @return List
+     */
+    public static List<Date> getDatesBetweenTwoDate(Date beginDate, Date endDate, int calendarType) {
+        List<Date> lDate = new ArrayList<Date>();
+        lDate.add(beginDate);// 把开始时间加入集合
+        Calendar cal = Calendar.getInstance();
+        // 使用给定的 Date 设置此 Calendar 的时间
+        cal.setTime(beginDate);
+        boolean bContinue = true;
+        while (bContinue) {
+            // 根据日历的规则,为给定的日历字段添加或减去指定的时间量
+            cal.add(calendarType, 1);
+            // 测试此日期是否在指定日期之后
+            if (endDate.after(cal.getTime())) {
+                lDate.add(cal.getTime());
+            } else {
+                break;
+            }
+        }
+        lDate.add(endDate);// 把结束时间加入集合
+        return lDate;
+    }
+
+    public static boolean after(Date date1,Date date2){
+        Calendar c1 = Calendar.getInstance();
+        c1.setTime(date1);
+        Calendar c2 = Calendar.getInstance();
+        c2.setTime(date2);
+        return c2.after(c1);
+    }
+}

+ 133 - 0
4dkankan-common-utils/src/main/java/com/fdkankan/common/util/FileMd5Util.java

@@ -0,0 +1,133 @@
+package com.fdkankan.common.util;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.security.MessageDigest;
+
+public class FileMd5Util {
+
+    public static final String KEY_MD5 = "MD5";
+    public static final String CHARSET_ISO88591 = "ISO-8859-1";
+
+    /**
+     * Get MD5 of one file:hex string,test OK!
+     *
+     * @param file
+     * @return
+     */
+    public static String getFileMD5(File file) {
+        if (!file.exists() || !file.isFile()) {
+            return null;
+        }
+        MessageDigest digest = null;
+        FileInputStream in = null;
+        byte buffer[] = new byte[1024];
+        int len;
+        try {
+            digest = MessageDigest.getInstance("MD5");
+            in = new FileInputStream(file);
+            while ((len = in.read(buffer, 0, 1024)) != -1) {
+                digest.update(buffer, 0, len);
+            }
+            in.close();
+        } catch (Exception e) {
+            e.printStackTrace();
+            return null;
+        }
+        byte by[] = digest.digest();
+        int i;
+        StringBuffer sbf = new StringBuffer();
+        for (int j = 0; j < by.length; j++) {
+            i = by[j];
+            if (i < 0) {
+                i += 256;
+            } else if (i < 16) {
+                sbf.append("0");    //因为大于16的有两位,因此小于16需要补位,
+            }
+            sbf.append(Integer.toHexString(i));
+
+        }
+
+        return sbf.toString();
+//        BigInteger bigInt = new BigInteger(1, digest.digest());
+//        return bigInt.toString(16);
+    }
+
+    /***
+     * Get MD5 of one file!test ok!
+     *
+     * @param filepath
+     * @return
+     */
+    public static String getFileMD5(String filepath) {
+        File file = new File(filepath);
+        return getFileMD5(file);
+    }
+
+    /**
+     * MD5 encrypt,test ok
+     *
+     * @param data
+     * @return byte[]
+     * @throws Exception
+     */
+    public static byte[] encryptMD5(byte[] data) throws Exception {
+
+        MessageDigest md5 = MessageDigest.getInstance(KEY_MD5);
+        md5.update(data);
+        return md5.digest();
+    }
+
+    public static byte[] encryptMD5(String data) throws Exception {
+        return encryptMD5(data.getBytes(CHARSET_ISO88591));
+    }
+
+    /***
+     * compare two file by Md5
+     *
+     * @param file1
+     * @param file2
+     * @return
+     */
+    public static boolean isSameMd5(File file1, File file2) {
+        String md5_1 = FileMd5Util.getFileMD5(file1);
+        String md5_2 = FileMd5Util.getFileMD5(file2);
+        return md5_1.equals(md5_2);
+    }
+
+    /***
+     * compare two file by Md5
+     *
+     * @param filepath1
+     * @param filepath2
+     * @return
+     */
+    public static boolean isSameMd5(String filepath1, String filepath2) {
+        File file1 = new File(filepath1);
+        File file2 = new File(filepath2);
+        return isSameMd5(file1, file2);
+    }
+
+    public static void main(String[] args){
+//        String path = "F:\\桌面\\";
+//
+//        StringBuffer sb = new StringBuffer(path + "20190925151119.h264");
+//        File dbFile = new File(sb.toString());
+//
+//        String fileMD5 = FileMd5Util.getFileMD5(dbFile);
+//        System.out.println(fileMD5);
+
+//        String path1 = "F:\\文档\\WeChat Files\\Iove-bing\\FileStorage\\File\\2020-05\\1.3.4-update.zip";
+//        File dbFile1 = new File(path1);
+//
+//        String fileMD51 = FileMd5Util.getFileMD5(dbFile1);
+//        System.out.println(fileMD51);
+
+//        BigInteger usedSpace = new BigInteger("0");
+//        BigInteger space = new BigInteger("560800515");
+//        usedSpace.add(space);
+//        System.out.println(usedSpace.intValue());
+        System.out.println("obj1: " + getFileMD5(new File("F:\\桌面\\c11m-T11-EA\\log\\i6VhiQ2Q-copy.obj")));
+        System.out.println("obj: " + getFileMD5(new File("F:\\桌面\\c11m-T11-EA\\log\\i6VhiQ2Q.obj")));
+    }
+}

+ 141 - 0
4dkankan-common-utils/src/main/java/com/fdkankan/common/util/FileSizeUtil.java

@@ -0,0 +1,141 @@
+package com.fdkankan.common.util;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.text.DecimalFormat;
+
+public class FileSizeUtil {
+
+    private static final String TAG=FileSizeUtil.class.getSimpleName();
+
+    public static final int SIZETYPE_B = 1;//获取文件大小单位为B的double值
+    public static final int SIZETYPE_KB = 2;//获取文件大小单位为KB的double值
+    public static final int SIZETYPE_MB = 3;//获取文件大小单位为MB的double值
+    public static final int SIZETYPE_GB = 4;//获取文件大小单位为GB的double值
+
+    /**
+     * 获取文件指定文件的指定单位的大小
+     *
+     * @param filePath 文件路径
+     * @param sizeType 获取大小的类型1为B、2为KB、3为MB、4为GB
+     * @return double值的大小
+     */
+    public static double getFileOrFilesSize(String filePath, int sizeType) {
+        File file = new File(filePath);
+        long blockSize = 0;
+        try {
+            if (file.isDirectory()) {
+                blockSize = getFileSizes(file);
+            } else {
+                blockSize = getFileSize(file);
+            }
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+        return formetFileSize(blockSize, sizeType);
+    }
+
+    /**
+     * 调用此方法自动计算指定文件或指定文件夹的大小
+     *
+     * @param filePath 文件路径
+     * @return 计算好的带B、KB、MB、GB的字符串
+     */
+    public static String getAutoFileOrFilesSize(String filePath) {
+        File file = new File(filePath);
+        long blockSize = 0;
+        try {
+            if (file.isDirectory()) {
+                blockSize = getFileSizes(file);
+            } else {
+                blockSize = getFileSize(file);
+            }
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+        return formatFileSize(blockSize);
+    }
+
+    /**
+     * 获取指定文件大小
+     */
+    private static long getFileSize(File file) throws Exception {
+        long size = 0;
+        if (file.exists()) {
+            FileInputStream fis = null;
+            fis = new FileInputStream(file);
+            size = fis.available();
+        } else {
+            file.createNewFile();
+        }
+        return size;
+    }
+
+    /**
+     * 获取指定文件夹
+     */
+    private static long getFileSizes(File f) throws Exception {
+        long size = 0;
+        File flist[] = f.listFiles();
+        assert flist != null;
+        for (File file : flist) {
+            if (file.isDirectory()) {
+                size = size + getFileSizes(file);
+            } else {
+                size = size + getFileSize(file);
+            }
+        }
+        return size;
+    }
+
+    /**
+     * 转换文件大小
+     */
+    public static String formatFileSize(long fileS) {
+        DecimalFormat df = new DecimalFormat("#.00");
+        String fileSizeString = "";
+        String wrongSize = "0B";
+        if (fileS == 0) {
+            return wrongSize;
+        }
+        if (fileS < 1024) {
+            fileSizeString = df.format((double) fileS) + "B";
+        } else if (fileS < 1048576) {
+            fileSizeString = df.format((double) fileS / 1024) + "KB";
+        } else if (fileS < 1073741824) {
+            fileSizeString = df.format((double) fileS / 1048576) + "MB";
+        } else if (fileS < 1099511627776L){
+            fileSizeString = df.format((double) fileS / 1073741824) + "GB";
+        } else if (fileS < 1125899906842624L){
+            fileSizeString = df.format((double) fileS / 1099511627776L) + "TB";
+        } else {
+            fileSizeString = df.format((double) fileS / 1125899906842624L) + "PB";
+        }
+        return fileSizeString;
+    }
+
+    /**
+     * 转换文件大小,指定转换的类型
+     */
+    public static double formetFileSize(long fileS, int sizeType) {
+        DecimalFormat df = new DecimalFormat("#.00");
+        double fileSizeLong = 0;
+        switch (sizeType) {
+            case SIZETYPE_B:
+                fileSizeLong = Double.valueOf(df.format((double) fileS));
+                break;
+            case SIZETYPE_KB:
+                fileSizeLong = Double.valueOf(df.format((double) fileS / 1024));
+                break;
+            case SIZETYPE_MB:
+                fileSizeLong = Double.valueOf(df.format((double) fileS / 1048576));
+                break;
+            case SIZETYPE_GB:
+                fileSizeLong = Double.valueOf(df.format((double) fileS / 1073741824));
+                break;
+            default:
+                break;
+        }
+        return fileSizeLong;
+    }
+}

+ 134 - 0
4dkankan-common-utils/src/main/java/com/fdkankan/common/util/FileUpload.java

@@ -0,0 +1,134 @@
+package com.fdkankan.common.util;
+
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.web.multipart.MultipartFile;
+
+import java.io.*;
+
+/**
+ * @author MeepoGuan
+ *
+ * <p>Description: 上传问题件</p>
+ *
+ * 2017年4月30日
+ *
+ */
+@Slf4j
+public class FileUpload {
+
+	/**
+	 * @param file 			//文件对象
+	 * @param filePath		//上传路径
+	 * @param fileName		//文件名
+	 * @return  文件名
+	 */
+	public static String fileUp(MultipartFile file, String filePath, String fileName) throws IOException {
+		String extName = ""; // 扩展名格式:
+
+		if (file.getOriginalFilename().lastIndexOf(".") >= 0){
+			extName = file.getOriginalFilename().substring(file.getOriginalFilename().lastIndexOf("."));
+		}
+		copyFile(file.getInputStream(), filePath, fileName+extName).replaceAll("-", "");
+
+		return fileName+extName;
+	}
+	
+	/**
+	 * 写文件到当前目录的upload目录中
+	 * 
+	 * @param in
+	 * @param dir
+	 * @param realName
+	 * @throws IOException
+	 */
+	private static String copyFile(InputStream in, String dir, String realName)
+			throws IOException {
+		File file = new File(dir, realName);
+		if (!file.exists()) {
+			if (!file.getParentFile().exists()) {
+				file.getParentFile().mkdirs();
+			}
+			file.createNewFile();
+		}
+        org.apache.commons.io.FileUtils.copyInputStreamToFile(in, file);
+		return realName;
+	}
+
+	/**
+	 * 断点续传
+	 * @param
+     */
+	public static String fileUpAgain(InputStream in, String filePath, String fileName, String realSavePath) throws IOException {
+		try{
+			File realFile = new File(realSavePath +  fileName);
+			File tempFile = new File(filePath + fileName);
+			if(!realFile.getParentFile().exists()){
+				realFile.getParentFile().mkdirs();
+			}
+			if(!tempFile.getParentFile().exists()){
+				tempFile.getParentFile().mkdirs();
+			}
+
+//			InputStream in = file.getInputStream();
+			long needSkipBytes = 0;
+			if (tempFile.exists()) {//续传
+				needSkipBytes = tempFile.length();
+			} else {//第一次传
+				tempFile.createNewFile();
+			}
+			log.info("跳过的字节数为:" + needSkipBytes);
+			in.skip(needSkipBytes);
+			RandomAccessFile tempRandAccessFile = new RandomAccessFile(tempFile, "rw");
+			tempRandAccessFile.seek(needSkipBytes);
+			byte[] buffer = new byte[1024];
+			int len = 0;
+			int count = 0;
+			while ((len = in.read(buffer)) > 0) {
+				tempRandAccessFile.write(buffer);
+				count++;
+			}
+			in.close();
+			tempRandAccessFile.close();
+			realFile.createNewFile();
+			if (fileCopy(tempFile, realFile)) {
+				tempFile.delete();
+			}
+		}catch (Exception e){
+			e.printStackTrace();
+		}
+		return realSavePath + fileName;
+	}
+
+	private static boolean fileCopy(File sourceFile, File targetFile) {
+		boolean success = true;
+		try {
+			FileInputStream in = new FileInputStream(sourceFile);
+			FileOutputStream out = new FileOutputStream(targetFile);
+			byte[] buffer = new byte[1024];
+			int len = 0;
+			while ((len = in.read(buffer)) > 0) {
+				out.write(buffer);
+			}
+			in.close();
+			out.close();
+		} catch (FileNotFoundException e) {
+			success = false;
+		} catch (IOException e) {
+			success = false;
+		}
+		return success;
+	}
+
+
+	public static void main(String[] args) {
+		try{
+			String path = "F:\\桌面\\20190925151119-T.h264";
+			FileInputStream f = new FileInputStream(path);
+			fileUpAgain(f, "G:\\javaProject\\9b918c802c3e40282267a89b5231f9a8_201905101446434643\\videos\\", "test123-T.h264", "G:\\javaProject\\9b918c802c3e40282267a89b5231f9a8_201905101446434643\\capture\\");
+//			copyFile(f, "G:\\javaProject\\zhoushan-system\\zhoushan-system-api\\src\\main\\resources\\static\\head", "test.h264");
+		}catch (Exception e){
+			e.printStackTrace();
+		}
+
+	}
+}

+ 1 - 1
4dkankan-common-utils/src/main/java/com/fdkankan/common/utils/FileUtil.java

@@ -1,4 +1,4 @@
-package com.fdkankan.common.utils;
+package com.fdkankan.common.util;
 
 import java.io.*;
 import java.nio.ByteBuffer;

+ 1 - 1
4dkankan-common-utils/src/main/java/com/fdkankan/common/utils/FileUtils.java

@@ -1,4 +1,4 @@
-package com.fdkankan.common.utils;
+package com.fdkankan.common.util;
 
 import com.alibaba.fastjson.JSONObject;
 import it.sauronsoftware.jave.*;

+ 1 - 1
4dkankan-common-utils/src/main/java/com/fdkankan/common/utils/JwtUtil.java

@@ -1,4 +1,4 @@
-package com.fdkankan.common.utils;
+package com.fdkankan.common.util;
 
 import com.auth0.jwt.JWT;
 import com.auth0.jwt.exceptions.JWTDecodeException;

+ 70 - 0
4dkankan-common-utils/src/main/java/com/fdkankan/common/util/LogoConfig.java

@@ -0,0 +1,70 @@
+package com.fdkankan.common.util;
+
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.core.io.ClassPathResource;
+
+import javax.imageio.ImageIO;
+import java.awt.*;
+import java.awt.geom.RoundRectangle2D;
+import java.awt.image.BufferedImage;
+import java.io.File;
+import java.io.IOException;
+
+@Slf4j
+public class LogoConfig {
+	/**
+     * 设置 logo  
+     * @param matrixImage 源二维码图片 
+     * @return 返回带有logo的二维码图片 
+     * @throws IOException 
+     * @author Administrator sangwenhao 
+     */  
+     public BufferedImage LogoMatrix(BufferedImage matrixImage, String logoPath) throws IOException{
+         /** 
+          * 读取二维码图片,并构建绘图对象 
+          */  
+         Graphics2D g2 = matrixImage.createGraphics();  
+           
+         int matrixWidth = matrixImage.getWidth();  
+         int matrixHeigh = matrixImage.getHeight();
+         /**
+          * 读取Logo图片
+          */
+         if(logoPath == null){
+//             logoPath = this.getClass().getResource("/static/img/logo.png").getPath();
+             ClassPathResource classPathResource = new ClassPathResource("static/img/logo.jpg");
+             logoPath  =classPathResource.getURL().getPath();
+         }
+         BufferedImage logo = null;
+         try {
+             logo = ImageIO.read(new File(logoPath));
+         }catch (IOException e){
+            log.info("读取图片流失败,path="+ logoPath, e);
+         }
+
+         //开始绘制图片  
+         g2.drawImage(logo,matrixWidth/5*2,matrixHeigh/5*2, matrixWidth/5, matrixHeigh/5, null);//绘制       
+         BasicStroke stroke = new BasicStroke(5,BasicStroke.CAP_ROUND,BasicStroke.JOIN_ROUND);   
+         g2.setStroke(stroke);// 设置笔画对象  
+         //指定弧度的圆角矩形  
+         RoundRectangle2D.Float round = new RoundRectangle2D.Float(matrixWidth/5*2, matrixHeigh/5*2, matrixWidth/5, matrixHeigh/5,20,20);  
+         g2.setColor(Color.white);  
+         g2.draw(round);// 绘制圆弧矩形  
+           
+         //设置logo 有一道灰色边框  
+         BasicStroke stroke2 = new BasicStroke(1,BasicStroke.CAP_ROUND,BasicStroke.JOIN_ROUND);   
+         g2.setStroke(stroke2);// 设置笔画对象  
+         RoundRectangle2D.Float round2 = new RoundRectangle2D.Float(matrixWidth/5*2+2, matrixHeigh/5*2+2, matrixWidth/5-4, matrixHeigh/5-4,20,20);  
+         g2.setColor(new Color(128,128,128));  
+         g2.draw(round2);// 绘制圆弧矩形  
+           
+         g2.dispose();  
+         matrixImage.flush() ;  
+         return matrixImage ;  
+     }
+
+//    public static void main(String[] args) {
+//        LogoConfig config = new LogoConfig()
+//        this.getClass().getResource("/static/img/logo.png").getPath();
+//    }
+}

+ 107 - 0
4dkankan-common-utils/src/main/java/com/fdkankan/common/util/MatrixToImageWriterUtil.java

@@ -0,0 +1,107 @@
+package com.fdkankan.common.util;
+
+import com.google.zxing.BarcodeFormat;
+import com.google.zxing.EncodeHintType;
+import com.google.zxing.MultiFormatWriter;
+import com.google.zxing.common.BitMatrix;
+import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel;
+import lombok.extern.slf4j.Slf4j;
+
+import javax.imageio.ImageIO;
+import java.awt.image.BufferedImage;
+import java.io.File;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.util.Hashtable;
+
+@Slf4j
+public class MatrixToImageWriterUtil {
+
+    private static final int BLACK = 0xFF000000;//用于设置图案的颜色
+    private static final int WHITE = 0xFFFFFFFF; //用于背景色  
+
+    private MatrixToImageWriterUtil() {}
+
+    public static BufferedImage toBufferedImage(BitMatrix matrix) {
+        int width = matrix.getWidth();
+        int height = matrix.getHeight();
+        BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
+        for (int x = 0; x < width; x++) {
+            for (int y = 0; y < height; y++) {
+                image.setRGB(x, y, (matrix.get(x, y) ? BLACK : WHITE));
+//              image.setRGB(x, y,  (matrix.get(x, y) ? Color.YELLOW.getRGB() : Color.CYAN.getRGB()));  
+            }
+        }
+        return image;
+    }
+
+    public static boolean writeToFile(BitMatrix matrix, String format, File file, String logoPath) throws IOException {
+        BufferedImage image = toBufferedImage(matrix);
+        //设置logo图标  
+        LogoConfig logoConfig = new LogoConfig();
+        image = logoConfig.LogoMatrix(image, logoPath);
+
+        File parFile = new File(file.getParent() + File.separator);
+        if (!parFile.exists()){
+            parFile.mkdirs();
+        }
+
+        if (!ImageIO.write(image, format, file)) {
+            //throw new IOException("Could not write an image of format " + format + " to " + file); 
+            log.info("Could not write an image of format " + format + " to " + file);
+            return false;
+        } else {
+            log.info("二维码生成成功!");
+            return true;
+        }
+    }
+
+    public static void writeToStream(BitMatrix matrix, String format, OutputStream stream) throws IOException {
+        BufferedImage image = toBufferedImage(matrix);
+        //设置logo图标  
+        LogoConfig logoConfig = new LogoConfig();
+        image = logoConfig.LogoMatrix(image, null);
+
+        if (!ImageIO.write(image, format, stream)) {
+            throw new IOException("Could not write an image of format " + format);
+        }
+    }
+
+    //url
+    public static boolean createQRCode(String url, String outPath, String logoPath) throws Exception {
+        // 生成二维码
+
+        int width = 3000; // 二维码图片宽度 300
+        int height = 3000; // 二维码图片高度300
+
+        String format = "jpg";// 二维码的图片格式 gif  
+
+        Hashtable<EncodeHintType, Object> hints = new Hashtable<EncodeHintType, Object>();
+        // 指定纠错等级,纠错级别(L 7%、M 15%、Q 25%、H 30%)
+        hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.H);
+        // 内容所使用字符集编码  
+        hints.put(EncodeHintType.CHARACTER_SET, "utf-8");
+//      hints.put(EncodeHintType.MAX_SIZE, 350);//设置图片的最大值  
+//      hints.put(EncodeHintType.MIN_SIZE, 100);//设置图片的最小值  
+        hints.put(EncodeHintType.MARGIN, 1);//设置二维码边的空度,非负数  
+
+        BitMatrix bitMatrix = new MultiFormatWriter().encode(url,
+                //编码类型,目前zxing支持:Aztec 2D,CODABAR 1D format,Code 39 1D,Code 93 1D ,Code 128 1D,  
+                //Data Matrix 2D , EAN-8 1D,EAN-13 1D,ITF (Interleaved Two of Five) 1D,  
+                //MaxiCode 2D barcode,PDF417,QR Code 2D,RSS 14,RSS EXPANDED,UPC-A 1D,UPC-E 1D,UPC/EAN extension,UPC_EAN_EXTENSION  
+                BarcodeFormat.QR_CODE,
+                width, //条形码的宽度  
+                height, //条形码的高度  
+                hints);//生成条形码时的一些配置,此项可选  
+
+        //File outputFile = new File("d:" + File.separator + "new-1.gif");//指定输出路径
+        File outputFile = new File(outPath);//指定输出路径
+        FileUtils.deleteFile(outPath);
+        return writeToFile(bitMatrix, format, outputFile, logoPath);
+    }
+
+    public static void main(String[] args) throws Exception{
+        MatrixToImageWriterUtil.createQRCode("https://www.4dkankan.com/spc.html?m=t-pnj0IJX", "F:/桌面/t-pnj0IJX.png", "G:\\javaProject\\4dkankan_v2-mini\\4dkankan-application\\target\\4dkankan_v2_mini\\WEB-INF\\classes\\static\\img\\logo.png");
+//        MatrixToImageWriterUtil.createQRCode("https://www.4dkankan.com/spc.html?m=t-pnj0IJX&lang=en", "F:/桌面/t-pnj0IJX_en.png", null);
+    }
+}

+ 86 - 0
4dkankan-common-utils/src/main/java/com/fdkankan/common/util/NumberUtils.java

@@ -0,0 +1,86 @@
+package com.fdkankan.common.util;
+
+import org.joda.time.DateTime;
+
+import java.util.Random;
+import java.util.UUID;
+import java.util.concurrent.atomic.AtomicInteger;
+
+public class NumberUtils {
+
+    private static AtomicInteger orderNum = new AtomicInteger(10);
+    private static AtomicInteger productNum = new AtomicInteger(10);
+    private static AtomicInteger skuNum = new AtomicInteger(10);
+
+    /**
+     * 生成订单编号
+     * @return
+     */
+    public static String getOrderNo() {
+        long orderNo = DateTime.now().getMillis() * 10000;
+        orderNo += orderNum.incrementAndGet();
+        return "O"+orderNo;
+    }
+
+    /**
+     * 生成订单编号
+     * @return
+     */
+    public static String getOrderSn(){
+//        DateTime dateTime = new DateTime();
+//        return dateTime.toString("yyyyMMddhhmmss") +RandomUtil.generateShortUuid();
+        long orderNo = DateTime.now().getMillis() * 10000;
+        orderNo += orderNum.incrementAndGet();
+        return "O"+orderNo;
+    }
+
+    /**
+     * 生成商品编号
+     * @return
+     */
+    public static String getGoodsNo() {
+        long productNo = DateTime.now().getMillis() * 10000;
+        productNo += productNum.incrementAndGet();
+        return "P"+productNo;
+    }
+
+    /**
+     * 生成sku编号
+     * @return
+     */
+    public static String getSkuNo() {
+        long skuNo = DateTime.now().getMillis() * 10000;
+        skuNo += skuNum.incrementAndGet();
+        return "U"+skuNo;
+    }
+
+    public static synchronized String create15() {
+        String strDate = new DateTime().toString("yyMMddHHmmss");
+        String random = getRandom620(3);
+        return strDate+random;
+    }
+
+    /**
+     * 获取6-10 的随机位数数字
+     * @param length	想要生成的长度
+     * @return result
+     */
+    public static String getRandom620(Integer length) {
+        String result = "";
+        Random rand = new Random();
+        int n = 20;
+        if (null != length && length > 0) {
+            n = length;
+        }
+        int randInt = 0;
+        for (int i = 0; i < n; i++) {
+            randInt = rand.nextInt(10);
+            result += randInt;
+        }
+        return result;
+    }
+
+    public static String getUUID(){
+        return UUID.randomUUID().toString().replace("-", "");
+    }
+}

+ 314 - 0
4dkankan-common-utils/src/main/java/com/fdkankan/common/util/OkHttpUtils.java

@@ -0,0 +1,314 @@
+package com.fdkankan.common.util;
+
+import lombok.extern.slf4j.Slf4j;
+import okhttp3.*;
+import org.springframework.util.CollectionUtils;
+
+import java.io.IOException;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Set;
+import java.util.concurrent.TimeUnit;
+import java.util.function.Consumer;
+
+//import org.springframework.http.HttpMethod;
+
+/**
+ * @author axin
+ * @since 2019-08-14
+ */
+@Slf4j
+public class OkHttpUtils {
+
+//    private static final Logger log = LoggerFactory.getLogger(OkHttpUtils.class);
+
+    private static final String HTTP_JSON = "application/json; charset=utf-8";
+    private static final String HTTP_FORM = "application/x-www-form-urlencoded; charset=utf-8";
+
+    //MEDIA_TYPE_TEXT post请求不是application/x-www-form-urlencoded的,全部直接返回,不作处理,即不会解析表单数据来放到request parameter map中。所以通过request.getParameter(name)是获取不到的。只能使用最原始的方式,读取输入流来获取。
+    private static final MediaType MEDIA_TYPE_TEXT = MediaType.parse("application/x-www-form-urlencoded; charset=utf-8");
+
+    private static final OkHttpClient okHttpClient = new OkHttpClient.Builder()
+            .connectTimeout(120, TimeUnit.SECONDS)
+            .readTimeout(120, TimeUnit.SECONDS)
+            .writeTimeout(120, TimeUnit.SECONDS)
+            .build();
+
+
+    /**
+     * get请求
+     * 对于小文档,响应体上的string()方法非常方便和高效。
+     * 但是,如果响应主体很大(大于1 MB),则应避免string(),
+     * 因为它会将整个文档加载到内存中。在这种情况下,将主体处理为流。
+     *
+     * @param url
+     * @return
+     */
+    public static String httpGet(String url) {
+        if (url == null || "".equals(url)) {
+            log.error("url为null!");
+            return "";
+        }
+
+        Request.Builder builder = new Request.Builder();
+        Request request = builder.get().url(url).build();
+        try {
+            Response response = okHttpClient.newCall(request).execute();
+            if (response.code() == 200) {
+                log.info("http GET 请求成功; [url={}]", url);
+                return response.body().string();
+            } else {
+                log.warn("Http GET 请求失败; [errorCode = {} , url={}]", response.code(), url);
+                log.info(response.body().string());
+            }
+        } catch (IOException e) {
+            throw new RuntimeException("同步http GET 请求失败,url:" + url, e);
+        }
+        return null;
+    }
+
+    public static String httpGet(String url, Map<String, String> headers) {
+        if (CollectionUtils.isEmpty(headers)) {
+            return httpGet(url);
+        }
+
+        Request.Builder builder = new Request.Builder();
+        headers.forEach((String key, String value) -> builder.header(key, value));
+        Request request = builder.get().url(url).build();
+        try {
+            Response response = okHttpClient.newCall(request).execute();
+            if (response.code() == 200) {
+                log.info("http GET 请求成功; [url={}]", url);
+                return response.body().string();
+            } else {
+                log.warn("Http GET 请求失败; [errorxxCode = {} , url={}]", response.code(), url);
+            }
+        } catch (IOException e) {
+            throw new RuntimeException("同步http GET 请求失败,url:" + url, e);
+        }
+        return null;
+    }
+
+    /**
+     * @author xiaobu
+     * @date 2019/3/4 15:58
+     * @param url , params]
+     * @return java.lang.String
+     * @descprition  post方式请求
+     * @version 1.0
+     */
+    public static String sendByPostMap(String url, Map<String, String> params) {
+        String result;
+        OkHttpClient client = new OkHttpClient();
+        StringBuilder content = new StringBuilder();
+        Set<Map.Entry<String, String>> entrys = params.entrySet();
+        Iterator<Map.Entry<String, String>> iterator = params.entrySet().iterator();
+        while (iterator.hasNext()) {
+            Map.Entry<String, String> entry = iterator.next();
+            content.append(entry.getKey()).append("=").append(entry.getValue());
+            if (iterator.hasNext()) {
+                content.append("&");
+            }
+        }
+
+        RequestBody requestBody = RequestBody.create(MEDIA_TYPE_TEXT, content.toString());
+        Request request = new Request.Builder().url(url).post(requestBody).build();
+        Response response = null;
+        try {
+            response = client.newCall(request).execute();
+            assert response.body() != null;
+            result = response.body().string();
+            System.out.println("result = " + result);
+            return result;
+        } catch (IOException e) {
+            e.printStackTrace();
+        }
+        return null;
+    }
+
+    /**
+     * 同步 POST调用 无Header
+     *
+     * @param url
+     * @param json
+     * @return
+     */
+    public static String httpPostJson(String url, String json) {
+        if (url == null || "".equals(url)) {
+            log.error("url为null!");
+            return "";
+        }
+
+        MediaType JSON = MediaType.parse(HTTP_JSON);
+        RequestBody body = RequestBody.create(JSON, json);
+        Request.Builder requestBuilder = new Request.Builder().url(url);
+        Request request = requestBuilder.post(body).build();
+        try {
+            Response response = okHttpClient.newCall(request).execute();
+            if (response.code() == 200) {
+                log.info("http Post 请求成功; [url={}, requestContent={}]", url, json);
+                return response.body().string();
+            } else {
+                log.warn("Http POST 请求失败; [ errorCode = {}, url={}, param={}]", response.code(), url, json);
+            }
+        } catch (IOException e) {
+            throw new RuntimeException("同步http请求失败,url:" + url, e);
+        }
+        return null;
+    }
+
+    /**
+     * 同步 POST调用 有Header
+     *
+     * @param url
+     * @param headers
+     * @param json
+     * @return
+     */
+    public static String httpPostJson(String url, Map<String, String> headers, String json) {
+        if (CollectionUtils.isEmpty(headers)) {
+            httpPostJson(url, json);
+        }
+
+        MediaType JSON = MediaType.parse(HTTP_JSON);
+        RequestBody body = RequestBody.create(JSON, json);
+        Request.Builder requestBuilder = new Request.Builder().url(url);
+        headers.forEach((k, v) -> requestBuilder.addHeader(k, v));
+        Request request = requestBuilder.post(body).build();
+        try {
+            Response response = okHttpClient.newCall(request).execute();
+            if (response.code() == 200) {
+                log.info("http Post 请求成功; [url={}, requestContent={}]", url, json);
+                return response.body().string();
+            } else {
+                log.warn("Http POST 请求失败; [ errorCode = {}, url={}, param={}]", response.code(), url, json);
+            }
+        } catch (IOException e) {
+            throw new RuntimeException("同步http请求失败,url:" + url, e);
+        }
+        return null;
+    }
+
+    /**
+     * 提交表单
+     * @param url
+     * @param content
+     * @param headers
+     * @return
+     */
+    public static String postDataByForm(String url, String content, Map<String, String> headers) {
+        MediaType JSON = MediaType.parse(HTTP_FORM);
+        RequestBody body = RequestBody.create(JSON, content);
+
+        Request.Builder requestBuilder = new Request.Builder().url(url);
+        if (headers != null && headers.size() > 0) {
+            headers.forEach((k, v) -> requestBuilder.addHeader(k, v));
+        }
+        Request request = requestBuilder
+                .post(body)
+                .build();
+
+        Response response = null;
+        try {
+            response = okHttpClient.newCall(request).execute();
+            if (response.code() == 200) {
+                log.info("postDataByForm; [postUrl={}, requestContent={}, responseCode={}]", url, content, response.code());
+                return response.body().string();
+            } else {
+                log.warn("Http Post Form请求失败,[url={}, param={}]", url, content);
+            }
+        } catch (IOException e) {
+            log.error("Http Post Form请求失败,[url={}, param={}]", url, content, e);
+            throw new RuntimeException("Http Post Form请求失败,url:" + url);
+        }
+        return null;
+    }
+
+    /**
+     * 异步Http调用参考模板:Get、Post、Put
+     * 需要异步调用的接口一般情况下你需要定制一个专门的Http方法
+     *
+     * @param httpMethod
+     * @param url
+     * @param content
+     * @return
+     */
+//    @Deprecated
+//    public static Future<Boolean> asyncHttpByJson(HttpMethod httpMethod, String url, Map<String, String> headers, String content) {
+//        MediaType JSON = MediaType.parse(HTTP_JSON);
+//        RequestBody body = RequestBody.create(JSON, content);
+//
+//        Request.Builder requestBuilder = new Request.Builder()
+//                .url(url);
+//
+//        if (!CollectionUtils.isEmpty(headers)) {
+//            headers.forEach((key, value) -> requestBuilder.header(key, value));
+//        }
+//
+//        switch (httpMethod) {
+//            case GET:
+//                requestBuilder.get();
+//                break;
+//            case POST:
+//                requestBuilder.post(body);
+//                break;
+//            default:
+//        }
+//
+//        Request request = requestBuilder.build();
+//        Call call = okHttpClient.newCall(request);
+//        call.enqueue(new Callback() {
+//            @Override
+//            public void onFailure(Call call, IOException e) {
+//                log.error("异步http {} 请求失败,[url={}, param={}]", httpMethod.name(), url, content);
+//                throw new RuntimeException("异步http请求失败,url:" + url);
+//            }
+//
+//            @Override
+//            public void onResponse(Call call, final Response response) throws IOException {
+//                if (response.code() == 200) {
+//                    System.out.println("需要加入异步回调操作");
+//                } else {
+//                    log.error("异步http {} 请求失败,错误码为{},请求参数为[url={}, param={}]", httpMethod.name(), response.code(), url, content);
+//                }
+//            }
+//        });
+//        return new AsyncResult(true);
+//    }
+
+    /**
+     * lambda表达式异步调用http模板,不建议使用
+     *
+     * @param request
+     * @param failure
+     * @param respConsumer
+     */
+    public static void asyncCall(Request request, Consumer<Exception> failure, Consumer<Response> respConsumer) {
+        okHttpClient.newCall(request).enqueue(new Callback() {
+            @Override
+            public void onFailure(Call call, IOException e) {
+                failure.accept(e);
+            }
+
+            @Override
+            public void onResponse(Call call, Response response) throws IOException {
+                respConsumer.accept(response);
+            }
+        });
+    }
+
+    //test
+    public static void main(String[] args) {
+//        String url = "http://192.168.0.30:8000/pro";
+//        JSONObject jsonObject = new JSONObject();
+//        jsonObject.put("name", "vr-t-2KZ4MQv-001");
+//        jsonObject.put("map", "t-2KZ4MQv");
+//        jsonObject.put("resolution", 1024);
+//        int num[] = new int[1];
+//        num[0] = -1;
+//        jsonObject.put("ids", num);
+//        System.out.println(httpPostJson(url, jsonObject.toJSONString()));
+        System.out.println(httpGet("http://192.168.0.165:8000/check"));
+    }
+
+}

+ 190 - 0
4dkankan-common-utils/src/main/java/com/fdkankan/common/util/PasswordUtils.java

@@ -0,0 +1,190 @@
+package com.fdkankan.common.util;
+
+import javax.crypto.Cipher;
+import javax.crypto.SecretKey;
+import javax.crypto.SecretKeyFactory;
+import javax.crypto.spec.PBEKeySpec;
+import javax.crypto.spec.PBEParameterSpec;
+import java.security.Key;
+import java.security.SecureRandom;
+
+public class PasswordUtils {
+
+
+    /**
+     * JAVA6支持以下任意一种算法 PBEWITHMD5ANDDES PBEWITHMD5ANDTRIPLEDES
+     * PBEWITHSHAANDDESEDE PBEWITHSHA1ANDRC2_40 PBKDF2WITHHMACSHA1
+     * */
+
+    /**
+     * 定义使用的算法为:PBEWITHMD5andDES算法
+     */
+    public static final String ALGORITHM = "PBEWithMD5AndDES";//加密算法
+    public static final String Salt = "63293188";//密钥
+
+    /**
+     * 定义迭代次数为1000次
+     */
+    private static final int ITERATIONCOUNT = 1000;
+
+    /**
+     * 获取加密算法中使用的盐值,解密中使用的盐值必须与加密中使用的相同才能完成操作. 盐长度必须为8字节
+     *
+     * @return byte[] 盐值
+     */
+    public static byte[] getSalt() throws Exception {
+        // 实例化安全随机数
+        SecureRandom random = new SecureRandom();
+        // 产出盐
+        return random.generateSeed(8);
+    }
+
+    public static byte[] getStaticSalt() {
+        // 产出盐
+        return Salt.getBytes();
+    }
+
+    /**
+     * 根据PBE密码生成一把密钥
+     *
+     * @param password 生成密钥时所使用的密码
+     * @return Key PBE算法密钥
+     */
+    private static Key getPBEKey(String password) {
+        // 实例化使用的算法
+        SecretKeyFactory keyFactory;
+        SecretKey secretKey = null;
+        try {
+            keyFactory = SecretKeyFactory.getInstance(ALGORITHM);
+            // 设置PBE密钥参数
+            PBEKeySpec keySpec = new PBEKeySpec(password.toCharArray());
+            // 生成密钥
+            secretKey = keyFactory.generateSecret(keySpec);
+        } catch (Exception e) {
+            // TODO Auto-generated catch block
+            e.printStackTrace();
+        }
+
+        return secretKey;
+    }
+
+    /**
+     * 加密明文字符串
+     *
+     * @param plaintext 待加密的明文字符串
+     * @param password  生成密钥时所使用的密码
+     * @param salt      盐值
+     * @return 加密后的密文字符串
+     * @throws Exception
+     */
+    public static String encrypt(String plaintext, String password, byte[] salt) {
+
+        Key key = getPBEKey(password);
+        byte[] encipheredData = null;
+        PBEParameterSpec parameterSpec = new PBEParameterSpec(salt, ITERATIONCOUNT);
+        try {
+            Cipher cipher = Cipher.getInstance(ALGORITHM);
+
+            cipher.init(Cipher.ENCRYPT_MODE, key, parameterSpec);
+
+            encipheredData = cipher.doFinal(plaintext.getBytes());
+        } catch (Exception e) {
+        }
+        return bytesToHexString(encipheredData);
+    }
+
+    /**
+     * 解密密文字符串
+     *
+     * @param ciphertext 待解密的密文字符串
+     * @param password   生成密钥时所使用的密码(如需解密,该参数需要与加密时使用的一致)
+     * @param salt       盐值(如需解密,该参数需要与加密时使用的一致)
+     * @return 解密后的明文字符串
+     * @throws Exception
+     */
+    public static String decrypt(String ciphertext, String password, byte[] salt) {
+
+        Key key = getPBEKey(password);
+        byte[] passDec = null;
+        PBEParameterSpec parameterSpec = new PBEParameterSpec(getStaticSalt(), ITERATIONCOUNT);
+        try {
+            Cipher cipher = Cipher.getInstance(ALGORITHM);
+
+            cipher.init(Cipher.DECRYPT_MODE, key, parameterSpec);
+
+            passDec = cipher.doFinal(hexStringToBytes(ciphertext));
+        } catch (Exception e) {
+            // TODO: handle exception
+        }
+        return new String(passDec);
+    }
+
+    /**
+     * 将字节数组转换为十六进制字符串
+     *
+     * @param src 字节数组
+     * @return
+     */
+    public static String bytesToHexString(byte[] src) {
+        StringBuilder stringBuilder = new StringBuilder("");
+        if (src == null || src.length <= 0) {
+            return null;
+        }
+        for (int i = 0; i < src.length; i++) {
+            int v = src[i] & 0xFF;
+            String hv = Integer.toHexString(v);
+            if (hv.length() < 2) {
+                stringBuilder.append(0);
+            }
+            stringBuilder.append(hv);
+        }
+        return stringBuilder.toString();
+    }
+
+    /**
+     * 将十六进制字符串转换为字节数组
+     *
+     * @param hexString 十六进制字符串
+     * @return
+     */
+    public static byte[] hexStringToBytes(String hexString) {
+        if (hexString == null || hexString.equals("")) {
+            return null;
+        }
+        hexString = hexString.toUpperCase();
+        int length = hexString.length() / 2;
+        char[] hexChars = hexString.toCharArray();
+        byte[] d = new byte[length];
+        for (int i = 0; i < length; i++) {
+            int pos = i * 2;
+            d[i] = (byte) (charToByte(hexChars[pos]) << 4 | charToByte(hexChars[pos + 1]));
+        }
+        return d;
+    }
+
+    private static byte charToByte(char c) {
+        return (byte) "0123456789ABCDEF".indexOf(c);
+    }
+
+    public static void main(String[] args) {
+
+        //管理后台密码加解密
+        String userName = "admin6";
+        String password = "123456";
+
+        try {
+            byte[] salt = PasswordUtils.getStaticSalt();
+            String ciphertext = PasswordUtils.encrypt(userName, password, salt);
+            System.out.println(ciphertext);
+            String plaintext = PasswordUtils.decrypt(ciphertext, password, salt);
+            System.out.println(plaintext);
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+
+
+
+
+    }
+
+}

+ 102 - 0
4dkankan-common-utils/src/main/java/com/fdkankan/common/util/PatternUtils.java

@@ -0,0 +1,102 @@
+package com.fdkankan.common.util;
+
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+public class PatternUtils {
+
+    public static boolean isEmail(String email) {
+        // 1、\\w+表示@之前至少要输入一个匹配字母或数字或下划线
+        // \\w 单词字符:[a-zA-Z_0-9] // 2、(\\w+\\.)表示域名. 如新浪邮箱域名是sina.com.cn
+        // {1,3}表示可以出现一次或两次或者三次.
+        String reg = "\\w+@(\\w+\\.){1,3}\\w+";
+        Pattern pattern = Pattern.compile(reg);
+        boolean flag = false;
+        if (email != null) {
+            Matcher matcher = pattern.matcher(email);
+            flag = matcher.matches();
+        }
+        return flag;
+    }
+
+    /**
+     * 判断身份证格式
+     *
+     * @param idNum
+     * @return
+     */
+    public static boolean isIdNum(String idNum) {
+        if (idNum == null || "".equals(idNum)) {
+            return false;
+        }
+        // 定义判别用户身份证号的正则表达式(15位或者18位,最后一位可以为字母)
+        String regularExpression = "(^[1-9]\\d{5}(18|19|20)\\d{2}((0[1-9])|(10|11|12))(([0-2][1-9])|10|20|30|31)\\d{3}[0-9Xx]$)|" +
+                "(^[1-9]\\d{5}\\d{2}((0[1-9])|(10|11|12))(([0-2][1-9])|10|20|30|31)\\d{3}$)";
+        //假设18位身份证号码:41000119910101123X  410001 19910101 123X
+        //^开头
+        //[1-9] 第一位1-9中的一个      4
+        //\\d{5} 五位数字           10001(前六位省市县地区)
+        //(18|19|20)                19(现阶段可能取值范围18xx-20xx年)
+        //\\d{2}                    91(年份)
+        //((0[1-9])|(10|11|12))     01(月份)
+        //(([0-2][1-9])|10|20|30|31)01(日期)
+        //\\d{3} 三位数字            123(第十七位奇数代表男,偶数代表女)
+        //[0-9Xx] 0123456789Xx其中的一个 X(第十八位为校验值)
+        //$结尾
+
+        //假设15位身份证号码:410001910101123  410001 910101 123
+        //^开头
+        //[1-9] 第一位1-9中的一个      4
+        //\\d{5} 五位数字           10001(前六位省市县地区)
+        //\\d{2}                    91(年份)
+        //((0[1-9])|(10|11|12))     01(月份)
+        //(([0-2][1-9])|10|20|30|31)01(日期)
+        //\\d{3} 三位数字            123(第十五位奇数代表男,偶数代表女),15位身份证不含X
+        //$结尾
+        boolean matches = idNum.matches(regularExpression);
+        //判断第18位校验值
+        if (matches) {
+            if (idNum.length() == 18) {
+                try {
+                    char[] charArray = idNum.toCharArray();
+                    //前十七位加权因子
+                    int[] idCardWi = {7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2};
+                    //这是除以11后,可能产生的11位余数对应的验证码
+                    String[] idCardY = {"1", "0", "X", "9", "8", "7", "6", "5", "4", "3", "2"};
+                    int sum = 0;
+                    for (int i = 0; i < idCardWi.length; i++) {
+                        int current = Integer.parseInt(String.valueOf(charArray[i]));
+                        int count = current * idCardWi[i];
+                        sum += count;
+                    }
+                    char idCardLast = charArray[17];
+                    int idCardMod = sum % 11;
+                    if (idCardY[idCardMod].toUpperCase().equals(String.valueOf(idCardLast).toUpperCase())) {
+                        return true;
+                    } else {
+                        return false;
+                    }
+
+                } catch (Exception e) {
+                    return false;
+                }
+            }
+
+        }
+        return matches;
+    }
+
+    //验证手机号码
+    public static boolean isPhoneNumber(String number) {
+        String rgx = "^1(3|4|5|7|8)\\d{9}$";
+//        return isCorrect(rgx, number);
+        return true;
+    }
+
+    //正则验证
+    public static boolean isCorrect(String rgx, String res) {
+        Pattern p = Pattern.compile(rgx);
+        Matcher m = p.matcher(res);
+        return m.matches();
+    }
+}

+ 465 - 0
4dkankan-common-utils/src/main/java/com/fdkankan/common/util/RSAEncrypt.java

@@ -0,0 +1,465 @@
+package com.fdkankan.common.util;
+
+import org.apache.commons.codec.binary.Base64;
+import org.springframework.util.ResourceUtils;
+import sun.misc.BASE64Decoder;
+
+import javax.crypto.BadPaddingException;
+import javax.crypto.Cipher;
+import javax.crypto.IllegalBlockSizeException;
+import javax.crypto.NoSuchPaddingException;
+import java.io.*;
+import java.security.*;
+import java.security.interfaces.RSAPrivateKey;
+import java.security.interfaces.RSAPublicKey;
+import java.security.spec.InvalidKeySpecException;
+import java.security.spec.PKCS8EncodedKeySpec;
+import java.security.spec.X509EncodedKeySpec;
+
+
+public class RSAEncrypt {
+
+    /**
+     * 字节数据转字符串专用集合
+     */
+    private static final char[] HEX_CHAR = {'0', '1', '2', '3', '4', '5', '6',
+            '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'};
+
+    private static final String PRIVATE_KEY = "classpath:key/private_pkcs8.pem";
+
+    private static final String PUBLIC_KEY = "classpath:key/public.pem";
+    /**
+     * RSA最大解密密文大小
+     */
+    private static final int MAX_DECRYPT_BLOCK = 128;
+    /**
+     * 随机生成密钥对
+     */
+    public static void genKeyPair(String filePath) {
+        // KeyPairGenerator类用于生成公钥和私钥对,基于RSA算法生成对象
+        KeyPairGenerator keyPairGen = null;
+        try {
+            keyPairGen = KeyPairGenerator.getInstance("RSA");
+        } catch (NoSuchAlgorithmException e) {
+            e.printStackTrace();
+        }
+        // 初始化密钥对生成器,密钥大小为96-1024位
+        keyPairGen.initialize(1024, new SecureRandom());
+        // 生成一个密钥对,保存在keyPair中
+        KeyPair keyPair = keyPairGen.generateKeyPair();
+        // 得到私钥
+        RSAPrivateKey privateKey = (RSAPrivateKey) keyPair.getPrivate();
+        // 得到公钥
+        RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic();
+        try {
+            // 得到公钥字符串
+            Base64 base64 = new Base64();
+            String publicKeyString = new String(base64.encode(publicKey.getEncoded()));
+            // 得到私钥字符串
+            String privateKeyString = new String(base64.encode(privateKey.getEncoded()));
+            // 将密钥对写入到文件
+            FileWriter pubfw = new FileWriter(filePath + PUBLIC_KEY);
+            FileWriter prifw = new FileWriter(filePath + PRIVATE_KEY);
+            BufferedWriter pubbw = new BufferedWriter(pubfw);
+            BufferedWriter pribw = new BufferedWriter(prifw);
+            pubbw.write(publicKeyString);
+            pribw.write(privateKeyString);
+            pubbw.flush();
+            pubbw.close();
+            pubfw.close();
+            pribw.flush();
+            pribw.close();
+            prifw.close();
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+    }
+
+    /**
+     * 从文件中输入流中加载公钥
+     *
+     * @throws Exception 加载公钥时产生的异常
+     */
+    public static String loadPublicKeyByFile() throws Exception {
+        try {
+            BufferedReader br = new BufferedReader(new FileReader(ResourceUtils.getFile(PUBLIC_KEY)));
+            String readLine = null;
+            StringBuilder sb = new StringBuilder();
+            while ((readLine = br.readLine()) != null) {
+                if (readLine.charAt(0) == '-') {
+                    continue;
+                } else {
+                    sb.append(readLine);
+                    sb.append('\r');
+                }
+            }
+            br.close();
+            return sb.toString();
+        } catch (IOException e) {
+            throw new Exception("公钥数据流读取错误");
+        } catch (NullPointerException e) {
+            throw new Exception("公钥输入流为空");
+        }
+    }
+
+    /**
+     * 从文件中输入流中加载公钥
+     *
+     * @throws Exception 加载公钥时产生的异常
+     */
+    public static String loadPublicKeyByFile(String publicKy) throws Exception {
+        try {
+            BufferedReader br = new BufferedReader(new FileReader(new File(publicKy)));
+            String readLine = null;
+            StringBuilder sb = new StringBuilder();
+            while ((readLine = br.readLine()) != null) {
+                if (readLine.charAt(0) == '-') {
+                    continue;
+                } else {
+                    sb.append(readLine);
+                    sb.append('\r');
+                }
+            }
+            br.close();
+            return sb.toString();
+        } catch (IOException e) {
+            throw new Exception("公钥数据流读取错误");
+        } catch (NullPointerException e) {
+            throw new Exception("公钥输入流为空");
+        }
+    }
+
+    /**
+     * 从字符串中加载公钥
+     *
+     * @param publicKeyStr 公钥数据字符串
+     * @throws Exception 加载公钥时产生的异常
+     */
+    public static RSAPublicKey loadPublicKeyByStr(String publicKeyStr)
+            throws Exception {
+        try {
+            BASE64Decoder base64 = new BASE64Decoder();
+            byte[] buffer = base64.decodeBuffer(publicKeyStr);
+            KeyFactory keyFactory = KeyFactory.getInstance("RSA");
+            X509EncodedKeySpec keySpec = new X509EncodedKeySpec(buffer);
+            return (RSAPublicKey) keyFactory.generatePublic(keySpec);
+        } catch (NoSuchAlgorithmException e) {
+            throw new Exception("无此算法");
+        } catch (InvalidKeySpecException e) {
+            throw new Exception("公钥非法");
+        } catch (NullPointerException e) {
+            throw new Exception("公钥数据为空");
+        }
+    }
+
+    /**
+     * 从文件中加载私钥
+     *
+     * @return 是否成功
+     * @throws Exception
+     */
+    public static String loadPrivateKeyByFile() throws Exception {
+        try {
+            InputStream inputStream = Thread.currentThread().getContextClassLoader().getResourceAsStream("key/private_pkcs8.pem");
+            StringBuilder builder = new StringBuilder();
+            InputStreamReader reader = new InputStreamReader(inputStream , "UTF-8" );
+            BufferedReader bfReader = new BufferedReader( reader );
+            String tmpContent = null;
+            while ((tmpContent = bfReader.readLine()) != null) {
+                if (tmpContent.charAt(0) == '-') {
+                    continue;
+                } else {
+                    builder.append(tmpContent);
+                    builder.append('\r');
+                }
+            }
+            bfReader.close();
+            return builder.toString();
+//            BufferedReader br = new BufferedReader(new FileReader(ResourceUtils.getFile(PRIVATE_KEY)));
+//            String readLine = null;
+//            StringBuilder sb = new StringBuilder();
+//            while ((readLine = br.readLine()) != null) {
+//                if (readLine.charAt(0) == '-') {
+//                    continue;
+//                } else {
+//                    sb.append(readLine);
+//                    sb.append('\r');
+//                }
+//            }
+//            br.close();
+//            return sb.toString();
+        } catch (IOException e) {
+            throw new Exception("私钥数据读取错误");
+        } catch (NullPointerException e) {
+            throw new Exception("私钥输入流为空");
+        }
+    }
+
+    /**
+     * 从文件中加载私钥
+     *
+     * @return 是否成功
+     * @throws Exception
+     */
+    public static String loadPrivateKeyByFile(String filePath) throws Exception {
+        try {
+            InputStream inputStream = new FileInputStream(filePath);
+            StringBuilder builder = new StringBuilder();
+            InputStreamReader reader = new InputStreamReader(inputStream , "UTF-8" );
+            BufferedReader bfReader = new BufferedReader( reader );
+            String tmpContent = null;
+            while ((tmpContent = bfReader.readLine()) != null) {
+                if (tmpContent.charAt(0) == '-') {
+                    continue;
+                } else {
+                    builder.append(tmpContent);
+                    builder.append('\r');
+                }
+            }
+            bfReader.close();
+            return builder.toString();
+//            BufferedReader br = new BufferedReader(new FileReader(ResourceUtils.getFile(PRIVATE_KEY)));
+//            String readLine = null;
+//            StringBuilder sb = new StringBuilder();
+//            while ((readLine = br.readLine()) != null) {
+//                if (readLine.charAt(0) == '-') {
+//                    continue;
+//                } else {
+//                    sb.append(readLine);
+//                    sb.append('\r');
+//                }
+//            }
+//            br.close();
+//            return sb.toString();
+        } catch (IOException e) {
+            throw new Exception("私钥数据读取错误");
+        } catch (NullPointerException e) {
+            throw new Exception("私钥输入流为空");
+        }
+    }
+
+    public static RSAPrivateKey loadPrivateKeyByStr(String privateKeyStr)
+            throws Exception {
+        try {
+            BASE64Decoder base64Decoder = new BASE64Decoder();
+            byte[] buffer = base64Decoder.decodeBuffer(privateKeyStr);
+            PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(buffer);
+            KeyFactory keyFactory = KeyFactory.getInstance("RSA");
+            return (RSAPrivateKey) keyFactory.generatePrivate(keySpec);
+        } catch (NoSuchAlgorithmException e) {
+            throw new Exception("无此算法");
+        } catch (InvalidKeySpecException e) {
+            throw new Exception("私钥非法");
+        } catch (NullPointerException e) {
+            throw new Exception("私钥数据为空");
+        }
+    }
+
+    /**
+     * 公钥加密过程
+     *
+     * @param publicKey     公钥
+     * @param plainTextData 明文数据
+     * @return
+     * @throws Exception 加密过程中的异常信息
+     */
+    public static byte[] encrypt(RSAPublicKey publicKey, byte[] plainTextData)
+            throws Exception {
+        if (publicKey == null) {
+            throw new Exception("加密公钥为空, 请设置");
+        }
+        Cipher cipher = null;
+        try {
+            // 使用默认RSA
+            cipher = Cipher.getInstance("RSA");
+            // cipher= Cipher.getInstance("RSA", new BouncyCastleProvider());
+            cipher.init(Cipher.ENCRYPT_MODE, publicKey);
+            byte[] output = cipher.doFinal(plainTextData);
+            return output;
+        } catch (NoSuchAlgorithmException e) {
+            throw new Exception("无此加密算法");
+        } catch (NoSuchPaddingException e) {
+            e.printStackTrace();
+            return null;
+        } catch (InvalidKeyException e) {
+            throw new Exception("加密公钥非法,请检查");
+        } catch (IllegalBlockSizeException e) {
+            throw new Exception("明文长度非法");
+        } catch (BadPaddingException e) {
+            throw new Exception("明文数据已损坏");
+        }
+    }
+
+    /**
+     * 私钥加密过程
+     *
+     * @param privateKey    私钥
+     * @param plainTextData 明文数据
+     * @return
+     * @throws Exception 加密过程中的异常信息
+     */
+    public static byte[] encrypt(RSAPrivateKey privateKey, byte[] plainTextData)
+            throws Exception {
+        if (privateKey == null) {
+            throw new Exception("加密私钥为空, 请设置");
+        }
+        Cipher cipher = null;
+        try {
+            // 使用默认RSA
+            cipher = Cipher.getInstance("RSA");
+            cipher.init(Cipher.ENCRYPT_MODE, privateKey);
+            byte[] output = cipher.doFinal(plainTextData);
+            return output;
+        } catch (NoSuchAlgorithmException e) {
+            throw new Exception("无此加密算法");
+        } catch (NoSuchPaddingException e) {
+            e.printStackTrace();
+            return null;
+        } catch (InvalidKeyException e) {
+            throw new Exception("加密私钥非法,请检查");
+        } catch (IllegalBlockSizeException e) {
+            throw new Exception("明文长度非法");
+        } catch (BadPaddingException e) {
+            throw new Exception("明文数据已损坏");
+        }
+    }
+
+    /**
+     * 私钥解密过程
+     *
+     * @param privateKey 私钥
+     * @param cipherData 密文数据
+     * @return 明文
+     * @throws Exception 解密过程中的异常信息
+     */
+    public static byte[] decrypt(RSAPrivateKey privateKey, byte[] cipherData)
+            throws Exception {
+        if (privateKey == null) {
+            throw new Exception("解密私钥为空, 请设置");
+        }
+        Cipher cipher = null;
+        try {
+            // 使用默认RSA
+            cipher = Cipher.getInstance("RSA");
+//             cipher= Cipher.getInstance("RSA", new BouncyCastleProvider());
+            cipher.init(Cipher.DECRYPT_MODE, privateKey);
+            /*byte[] output = cipher.doFinal(cipherData);
+            return output;*/
+            return getDecrytedData(cipherData, cipher);
+        } catch (NoSuchAlgorithmException e) {
+            throw new Exception("无此解密算法");
+        } catch (NoSuchPaddingException e) {
+            e.printStackTrace();
+            return null;
+        } catch (InvalidKeyException e) {
+            throw new Exception("解密私钥非法,请检查");
+        } catch (IllegalBlockSizeException e) {
+            throw new Exception("密文长度非法");
+        } catch (BadPaddingException e) {
+            throw new Exception("密文数据已损坏");
+        }
+    }
+
+    /**
+     * 公钥解密过程
+     *
+     * @param publicKey  公钥
+     * @param cipherData 密文数据
+     * @return 明文
+     * @throws Exception 解密过程中的异常信息
+     */
+    public static byte[] decrypt(RSAPublicKey publicKey, byte[] cipherData)
+            throws Exception {
+        if (publicKey == null) {
+            throw new Exception("解密公钥为空, 请设置");
+        }
+        Cipher cipher = null;
+        try {
+            // 使用默认RSA
+            cipher = Cipher.getInstance("RSA");
+            // cipher= Cipher.getInstance("RSA", new BouncyCastleProvider());
+            cipher.init(Cipher.DECRYPT_MODE, publicKey);
+            /*byte[] output = cipher.doFinal(cipherData);
+            return output;*/
+            return getDecrytedData(cipherData, cipher);
+        } catch (NoSuchAlgorithmException e) {
+            throw new Exception("无此解密算法");
+        } catch (NoSuchPaddingException e) {
+            e.printStackTrace();
+            return null;
+        } catch (InvalidKeyException e) {
+            throw new Exception("解密公钥非法,请检查");
+        } catch (IllegalBlockSizeException e) {
+            throw new Exception("密文长度非法");
+        } catch (BadPaddingException e) {
+            throw new Exception("密文数据已损坏");
+        }
+    }
+
+    private static byte[] getDecrytedData(byte[] cipherData, Cipher cipher) throws IllegalBlockSizeException, BadPaddingException, IOException {
+//        int inputLen = cipherData.length;
+////        ByteArrayOutputStream out = new ByteArrayOutputStream();
+////        int offSet = 0;
+////        byte[] cache;
+////        int i = 0;
+////        // 对数据分段解密
+////        while (inputLen - offSet > 0) {
+////            if (inputLen - offSet > MAX_DECRYPT_BLOCK) {
+////                cache = cipher.doFinal(cipherData, offSet, MAX_DECRYPT_BLOCK);
+////            } else {
+////                cache = cipher.doFinal(cipherData, offSet, inputLen - offSet);
+////            }
+////            out.write(cache, 0, cache.length);
+////            i++;
+////            offSet = i * MAX_DECRYPT_BLOCK;
+////        }
+////        byte[] decryptedData = out.toByteArray();
+////        out.close();
+////        return decryptedData;
+        int inputLen = cipherData.length;
+        ByteArrayOutputStream out = new ByteArrayOutputStream();
+        int offSet = 0;
+
+        for(int i = 0; inputLen - offSet > 0; offSet = i * 256) {
+            byte[] cache;
+            if(inputLen - offSet > 256) {
+                cache = cipher.doFinal(cipherData, offSet, 256);
+            } else {
+                cache = cipher.doFinal(cipherData, offSet, inputLen - offSet);
+            }
+            out.write(cache, 0, cache.length);
+            ++i;
+        }
+
+        byte[] decryptedData = out.toByteArray();
+        out.close();
+        return decryptedData;
+    }
+
+    /**
+     * 字节数据转十六进制字符串
+     *
+     * @param data 输入数据
+     * @return 十六进制内容
+     */
+    public static String byteArrayToString(byte[] data) {
+        StringBuilder stringBuilder = new StringBuilder();
+        for (int i = 0; i < data.length; i++) {
+            // 取出字节的高四位 作为索引得到相应的十六进制标识符 注意无符号右移
+            stringBuilder.append(HEX_CHAR[(data[i] & 0xf0) >>> 4]);
+            // 取出字节的低四位 作为索引得到相应的十六进制标识符
+            stringBuilder.append(HEX_CHAR[(data[i] & 0x0f)]);
+            if (i < data.length - 1) {
+                stringBuilder.append(' ');
+            }
+        }
+        return stringBuilder.toString();
+    }
+
+    public static void main(String[] args) throws Exception {
+
+
+
+    }
+
+}

+ 49 - 0
4dkankan-common-utils/src/main/java/com/fdkankan/common/util/RandomUtil.java

@@ -0,0 +1,49 @@
+package com.fdkankan.common.util;
+
+import java.util.Random;
+import java.util.UUID;
+
+public class RandomUtil {
+    public static String[] chars = new String[] { "a", "b", "c", "d", "e", "f",
+            "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s",
+            "t", "u", "v", "w", "x", "y", "z", "0", "1", "2", "3", "4", "5",
+            "6", "7", "8", "9", "A", "B", "C", "D", "E", "F", "G", "H", "I",
+            "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V",
+            "W", "X", "Y", "Z" };
+
+    public static String generateShortUuid() {
+        StringBuffer shortBuffer = new StringBuffer();
+        String uuid = UUID.randomUUID().toString().replace("-", "");
+        int index = 0;
+        for (int i = 0; i < 10; i++) {
+            index = i;
+            if(index >= 8){
+                index = i % 8;
+                uuid = UUID.randomUUID().toString().replace("-", "");
+            }
+            String str = uuid.substring(index * 4, index * 4 + 4);
+            int x = Integer.parseInt(str, 16);
+            shortBuffer.append(chars[x % 0x3E]);
+        }
+        return shortBuffer.toString();
+
+    }
+
+    /**
+     * 获取随机字符串(相机sn码)
+     *
+     * @param num
+     * @return
+     */
+    public static String getRandomNum(Integer num) {
+        String base = "0123456789ABCDEF";
+        Random random = new Random();
+        StringBuffer sb = new StringBuffer();
+        for (int i = 0; i < num; i++) {
+            int number = random.nextInt(base.length());
+            sb.append(base.charAt(number));
+        }
+        return sb.toString();
+    }
+
+}

+ 206 - 0
4dkankan-common-utils/src/main/java/com/fdkankan/common/util/RubberSheetingUtil.java

@@ -0,0 +1,206 @@
+package com.fdkankan.common.util;
+
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.stereotype.Component;
+
+import javax.crypto.Mac;
+import javax.crypto.spec.SecretKeySpec;
+import java.io.UnsupportedEncodingException;
+import java.net.URLEncoder;
+import java.text.SimpleDateFormat;
+import java.util.*;
+
+/**
+ * Created by Hb_zzZ on 2020/8/25.
+ */
+@Slf4j
+@Component
+public class RubberSheetingUtil {
+
+    @Value("${scaling.group.id}")
+    private String ScalingGroupId;
+
+    @Value("${scaling.rule.ari}")
+    private String ScalingRuleAri;
+
+    private static String AccessKeyId = "LTAI4GKZQBM1zZZZBJK7nGjR";
+
+    private String sign(String action, Map<String, String> parameters) throws Exception{
+        final String HTTP_METHOD = "GET";
+
+        final String ALGORITHM = "HmacSHA1";
+        final String ENCODING = "UTF-8";
+        String keySecret = "bo1ura8KODXASVyZ5fofy0fWFILumz&";
+
+        // 对参数进行排序
+        String[] sortedKeys = parameters.keySet().toArray(new String[]{});
+        Arrays.sort(sortedKeys);
+
+        final String SEPARATOR = "&";
+
+        // 生成stringToSign字符串
+        StringBuilder stringToSign = new StringBuilder();
+        stringToSign.append(HTTP_METHOD).append(SEPARATOR);
+        stringToSign.append(percentEncode("/")).append(SEPARATOR);
+
+        StringBuilder canonicalizedQueryString = new StringBuilder();
+        for(String key : sortedKeys) {
+            // 这里注意对key和value进行编码
+            canonicalizedQueryString.append("&")
+                    .append(percentEncode(key)).append("=")
+                    .append(percentEncode(parameters.get(key)));
+        }
+//        System.out.println("canonicalizedQueryString:" + canonicalizedQueryString.toString());
+
+        // 这里注意对canonicalizedQueryString进行编码
+        stringToSign.append(percentEncode(
+                canonicalizedQueryString.toString().substring(1)));
+//        System.out.println("stringToSign:" + stringToSign.toString());
+
+        Mac mac = Mac.getInstance(ALGORITHM);
+        mac.init(new SecretKeySpec(keySecret.getBytes(ENCODING), ALGORITHM));
+        byte[] signData = mac.doFinal(stringToSign.toString().getBytes(ENCODING));
+
+        String signature = new String(org.apache.commons.codec.binary.Base64.encodeBase64(signData));
+        return signature;
+    }
+
+    private static final String ISO8601_DATE_FORMAT = "yyyy-MM-dd'T'HH:mm:ss'Z'";
+    private static String formatIso8601Date(Date date) {
+        SimpleDateFormat df = new SimpleDateFormat(ISO8601_DATE_FORMAT);
+        df.setTimeZone(new SimpleTimeZone(0, "GMT"));
+        return df.format(date);
+    }
+
+    private static final String ENCODING = "UTF-8";
+
+    private static String percentEncode(String value) throws UnsupportedEncodingException {
+        return value != null ? URLEncoder.encode(value, ENCODING).replace("+", "%20").replace("*", "%2A").replace("%7E", "~") : null;
+    }
+
+    public static void main(String[] args) {
+
+        String text = "";
+        for(int i = 0, len = 100; i < len; i ++){
+//            createEcs();
+        }
+//        System.out.println(deleteEcs("i-wz95huv20p8v6csu6q1q"));
+
+//        try{
+//            System.out.println(FileUtils.readFile("C:\\Users\\hisun\\Downloads\\hosts.txt"));
+//            System.out.println(1);
+//        }catch (Exception e){
+//            e.printStackTrace();
+//        }
+    }
+
+    public String createEcs(){
+        try {
+
+            boolean tag = true;
+            Map<String, String> parameters = null;
+            while (tag){
+                parameters = new HashMap<String, String>();
+                // 加入请求参数
+                parameters.put("Action", "ExecuteScalingRule");
+                parameters.put("ScalingRuleAri", ScalingRuleAri);
+                parameters.put("Version", "2014-08-28");
+                parameters.put("AccessKeyId", AccessKeyId);
+                parameters.put("Timestamp", formatIso8601Date(new Date()));
+                parameters.put("SignatureMethod", "HMAC-SHA1");
+                parameters.put("SignatureVersion", "1.0");
+                parameters.put("SignatureNonce", UUID.randomUUID().toString());
+                parameters.put("Format", "JSON");
+
+                String signature = sign("AttachInstances", parameters);
+                System.out.println(signature);
+                if(!signature.contains("+") && !signature.contains("/")){
+                    tag = false;
+                }
+                parameters.put("Signature", signature);
+            }
+
+
+            StringBuffer parameterBuffer = new StringBuffer();
+            if (parameters != null) {
+                Iterator iterator = parameters.keySet().iterator();
+                String key = null;
+                String value = null;
+                while (iterator.hasNext()) {
+                    key = (String) iterator.next();
+                    if (parameters.get(key) != null) {
+                        value = (String) parameters.get(key);
+                    } else {
+                        value = "";
+                    }
+
+                    parameterBuffer.append(key).append("=").append(value);
+                    if (iterator.hasNext()) {
+                        parameterBuffer.append("&");
+                    }
+                }
+            }
+//            System.out.println("POST parameter : " + parameterBuffer.toString());
+            return OkHttpUtils.httpGet("http://ess.aliyuncs.com?" + parameterBuffer.toString());
+        }catch (Exception e){
+            e.printStackTrace();
+        }
+
+        return null;
+    }
+
+    public String deleteEcs(String id){
+        try {
+            boolean tag = true;
+            Map<String, String> parameters = null;
+            while (tag){
+                parameters = new HashMap<String, String>();
+                // 加入请求参数
+                parameters.put("Action", "RemoveInstances");
+                parameters.put("InstanceId.1", id);
+                parameters.put("ScalingGroupId", ScalingGroupId);
+                parameters.put("Version", "2014-08-28");
+                parameters.put("AccessKeyId", AccessKeyId);
+                parameters.put("Timestamp", formatIso8601Date(new Date()));
+                parameters.put("SignatureMethod", "HMAC-SHA1");
+                parameters.put("SignatureVersion", "1.0");
+                parameters.put("SignatureNonce", UUID.randomUUID().toString());
+                parameters.put("Format", "JSON");
+
+                String signature = sign("AttachInstances", parameters);
+//            System.out.println(signature);
+                if(!signature.contains("+") && !signature.contains("/")){
+                    tag = false;
+                }
+                parameters.put("Signature", signature);
+            }
+
+            StringBuffer parameterBuffer = new StringBuffer();
+            if (parameters != null) {
+                Iterator iterator = parameters.keySet().iterator();
+                String key = null;
+                String value = null;
+                while (iterator.hasNext()) {
+                    key = (String) iterator.next();
+                    if (parameters.get(key) != null) {
+                        value = (String) parameters.get(key);
+                    } else {
+                        value = "";
+                    }
+
+                    parameterBuffer.append(key).append("=").append(value);
+                    if (iterator.hasNext()) {
+                        parameterBuffer.append("&");
+                    }
+                }
+            }
+//            System.out.println("POST parameter : " + parameterBuffer.toString());
+            return OkHttpUtils.httpGet("http://ess.aliyuncs.com?" + parameterBuffer.toString());
+        }catch (Exception e){
+            e.printStackTrace();
+        }
+        return null;
+    }
+
+}

+ 1 - 1
4dkankan-common-utils/src/main/java/com/fdkankan/common/utils/SHAUtils.java

@@ -1,4 +1,4 @@
-package com.fdkankan.common.utils;
+package com.fdkankan.common.util;
 
 import java.io.UnsupportedEncodingException;
 import java.security.MessageDigest;

+ 32 - 0
4dkankan-common-utils/src/main/java/com/fdkankan/common/util/SecurityUtil.java

@@ -0,0 +1,32 @@
+package com.fdkankan.common.util;
+
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+
+public class SecurityUtil {
+    public static String MD52(String md5){
+        try {
+            MessageDigest md = MessageDigest.getInstance("MD5");
+            byte[] digest = md.digest(md5.getBytes());
+            StringBuffer sb = new StringBuffer();
+            for (int i = 0; i < digest.length; i++) {
+                sb.append(Integer.toHexString((digest[i] & 0xFF) | 0x100).substring(1,3));
+            }
+            return sb.toString();
+        } catch (NoSuchAlgorithmException e) {
+            e.printStackTrace();
+        }
+        return null;
+    }
+
+    public static String MD5(String inStr){
+
+        char[] a = inStr.toCharArray();
+        for (int i = 0; i < a.length; i++){
+            a[i] = (char) (a[i] ^ 't');
+        }
+        String s = new String(a);
+        return s;
+
+    }
+}

+ 135 - 0
4dkankan-common-utils/src/main/java/com/fdkankan/common/util/SnowflakeIdGenerator.java

@@ -0,0 +1,135 @@
+package com.fdkankan.common.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 SnowflakeIdGenerator {
+
+    // ==============================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 SnowflakeIdGenerator(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();
+    }
+}

+ 12 - 0
4dkankan-common-utils/src/main/java/com/fdkankan/common/util/StrExtUtil.java

@@ -0,0 +1,12 @@
+package com.fdkankan.common.util;
+
+import cn.hutool.core.util.StrUtil;
+
+public class StrExtUtil extends StrUtil {
+
+    public static void main(String[] args) {
+        String test = "";
+        System.out.println(isBlank(test));
+    }
+
+}

+ 1 - 1
4dkankan-common-utils/src/main/java/com/fdkankan/common/utils/StreamGobbler.java

@@ -1,4 +1,4 @@
-package com.fdkankan.common.utils;
+package com.fdkankan.common.util;
 
 import java.io.*;
 

+ 112 - 0
4dkankan-common-utils/src/main/java/com/fdkankan/common/util/WeiXinUtils.java

@@ -0,0 +1,112 @@
+package com.fdkankan.common.util;
+
+import com.alibaba.fastjson.JSONObject;
+import lombok.extern.slf4j.Slf4j;
+
+import java.io.InputStream;
+import java.net.HttpURLConnection;
+import java.net.URL;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+
+@Slf4j
+public class WeiXinUtils {
+
+	/**
+	 * access_token是公众号的全局唯一接口调用凭据
+	 * */
+//	private static String appId ="wxa59ca7a81b848e57";// 第三方用户唯一凭证
+//	private static String secret = "adbcef23b06639e73f1a8115fabec064";// 第三方用户唯一凭证密钥,即appsecret
+
+	private static String appId ="wx99f149afc37cb405";// 第三方用户唯一凭证
+	private static String secret = "28c1124796c43f98f1bc2c936f9931d2";// 第三方用户唯一凭证密钥,即appsecret
+
+	public static String getAccessToken(){
+		String accessToken = "";
+		String grantType = "client_credential";// 获取access_token填写client_credential
+
+		// 这个url链接地址和参数皆不能变
+		String url = "https://api.weixin.qq.com/cgi-bin/token?grant_type=" + grantType + "&appid=" + appId + "&secret="+ secret;
+		try {
+			URL urlGet = new URL(url);
+			HttpURLConnection http = (HttpURLConnection) urlGet.openConnection();
+			http.setRequestMethod("GET"); // 必须是get方式请求
+			http.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
+			http.setDoOutput(true);
+			http.setDoInput(true);
+			System.setProperty("sun.net.client.defaultConnectTimeout", "30000");// 连接超时30秒
+			System.setProperty("sun.net.client.defaultReadTimeout", "30000"); // 读取超时30秒
+			http.connect();
+			InputStream is = http.getInputStream();
+			int size = is.available();
+			byte[] jsonBytes = new byte[size];
+			is.read(jsonBytes);
+			String message = new String(jsonBytes, "UTF-8");
+			log.debug("获取access_token返回的message:"+message);
+			JSONObject demoJson = JSONObject.parseObject(message);
+			log.info("获取access_token返回的json:"+demoJson);
+			accessToken = demoJson.getString("access_token");
+			log.info("新获取的access_token:"+accessToken);
+			is.close();
+		}catch (Exception e){
+			log.debug("获取access_token发生异常",e);
+		}
+		return accessToken;
+	}
+	
+	/**
+	 * sapi_ticket是公众号用于调用微信JS接口的临时票据,获得jsapi_ticket之后,就可以生成JSSDK权限验证的签名了
+	 * 参与签名的字段包括noncestr(随机字符串), 有效的jsapi_ticket, timestamp(时间戳), url(当前网页的URL,不包含#及其后面部分) 
+	 * @param accessToken
+	 * @return
+	 */
+	public static String getTicket(String accessToken) {
+		String ticket = null;
+		String url = "https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token=" + accessToken + "&type=jsapi";// 这个url链接和参数不能变
+		try {
+			URL urlGet = new URL(url);
+			HttpURLConnection http = (HttpURLConnection) urlGet.openConnection();
+			http.setRequestMethod("GET"); // 必须是get方式请求
+			http.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
+			http.setDoOutput(true);
+			http.setDoInput(true);
+			System.setProperty("sun.net.client.defaultConnectTimeout", "30000");// 连接超时30秒
+			System.setProperty("sun.net.client.defaultReadTimeout", "30000"); // 读取超时30秒
+			http.connect();
+			InputStream is = http.getInputStream();
+			int size = is.available();
+			byte[] jsonBytes = new byte[size];
+			is.read(jsonBytes);
+			String message = new String(jsonBytes, "UTF-8");
+			JSONObject demoJson = JSONObject.parseObject(message);
+			ticket = demoJson.getString("ticket");
+			is.close();
+		} catch (Exception e) {
+			log.error("获取ticket发生错误", e);
+		}
+		return ticket;
+	}
+ 
+	public static String SHA1(String decript) {
+		try {
+			MessageDigest digest = MessageDigest.getInstance("SHA-1");
+			digest.update(decript.getBytes());
+			byte messageDigest[] = digest.digest();
+			// Create Hex String
+			StringBuffer hexString = new StringBuffer();
+			// 字节数组转换为 十六进制 数
+			for (int i = 0; i < messageDigest.length; i++) {
+				String shaHex = Integer.toHexString(messageDigest[i] & 0xFF);
+				if (shaHex.length() < 2) {
+					hexString.append(0);
+				}
+				hexString.append(shaHex);
+			}
+			return hexString.toString();
+ 
+		} catch (NoSuchAlgorithmException e) {
+			log.error("SHA1发生错误", e);
+		}
+		return "";
+	}
+}

+ 1 - 3
4dkankan-utils-redis/pom.xml

@@ -6,7 +6,7 @@
     <parent>
         <groupId>com.fdkankan</groupId>
         <artifactId>4dkankan-utils</artifactId>
-        <version>2.0.0</version>
+        <version>2.0.3</version>
     </parent>
     <modelVersion>4.0.0</modelVersion>
 
@@ -22,12 +22,10 @@
         <dependency>
             <groupId>org.apache.commons</groupId>
             <artifactId>commons-lang3</artifactId>
-            <version>3.10</version>
         </dependency>
         <dependency>
             <groupId>org.apache.commons</groupId>
             <artifactId>commons-pool2</artifactId>
-            <version>2.5.0</version>
         </dependency>
     </dependencies>
 

+ 17 - 0
pom.xml

@@ -86,6 +86,19 @@
                 <artifactId>log4j-to-slf4j</artifactId>
                 <version>2.17.0</version>
             </dependency>
+
+            <dependency>
+                <groupId>org.apache.commons</groupId>
+                <artifactId>commons-lang3</artifactId>
+                <version>3.10</version>
+            </dependency>
+
+            <dependency>
+                <groupId>org.apache.commons</groupId>
+                <artifactId>commons-pool2</artifactId>
+                <version>2.5.0</version>
+            </dependency>
+
         </dependencies>
     </dependencyManagement>
 
@@ -98,6 +111,10 @@
                     <groupId>org.apache.maven.plugins</groupId>
                     <artifactId>maven-compiler-plugin</artifactId>
                     <version>3.8.1</version>
+                    <configuration>
+                        <source>8</source>
+                        <target>8</target>
+                    </configuration>
                 </plugin>
             </plugins>
         </pluginManagement>