Переглянути джерело

Merge branch 'master' into project-local-jg

dengsixing 3 місяців тому
батько
коміт
6117e20657
34 змінених файлів з 1149 додано та 123 видалено
  1. 5 0
      4dkankan-common-utils/src/main/java/com/fdkankan/common/constant/ErrorCode.java
  2. 5 1
      4dkankan-common-utils/src/main/java/com/fdkankan/common/constant/SceneSource.java
  3. 3 1
      4dkankan-common-web/src/main/java/com/fdkankan/web/response/BaseResponseAdvice.java
  4. 29 0
      4dkankan-common-web/src/main/java/com/fdkankan/web/util/RSAEncrypt.java
  5. 1 1
      4dkankan-utils-dxf/pom.xml
  6. 1 1
      4dkankan-utils-dxf/src/main/java/com/fdkankan/dxf/generate/DxfDocWriter.java
  7. 2 2
      4dkankan-utils-dxf/src/main/java/com/fdkankan/dxf/generate/model/DxfText.java
  8. 16 0
      4dkankan-utils-dxf/src/main/java/com/fdkankan/dxf/math/MathArcUtil.java
  9. 87 11
      4dkankan-utils-dxf/src/main/java/com/fdkankan/dxf/parse/utils/FdJsonToDxfUtil.java
  10. 170 0
      4dkankan-utils-dxf/src/main/java/com/fdkankan/dxf/parse/utils/LaserMeterToDxfUtil.java
  11. 4 0
      4dkankan-utils-filestorage/src/main/java/com/fdkankan/filestorage/FileStorageTemplate.java
  12. 22 0
      4dkankan-utils-filestorage/src/main/java/com/fdkankan/filestorage/aliyun/AliyunOssTemplate.java
  13. 19 0
      4dkankan-utils-filestorage/src/main/java/com/fdkankan/filestorage/aws/AwsTemplate.java
  14. 19 0
      4dkankan-utils-filestorage/src/main/java/com/fdkankan/filestorage/cos/CosTemplate.java
  15. 28 0
      4dkankan-utils-filestorage/src/main/java/com/fdkankan/filestorage/minio/MinioTemplate.java
  16. 45 0
      4dkankan-utils-filestorage/src/main/java/com/fdkankan/filestorage/util/DomainUtil.java
  17. 35 4
      4dkankan-utils-fyun-oss/src/main/java/com/fdkankan/fyun/oss/OssFileService.java
  18. 6 1
      4dkankan-utils-geo-query/pom.xml
  19. 2 2
      4dkankan-utils-geo-query/src/main/java/com/fdkankan/geo/GeoQueryUtil.java
  20. 53 0
      4dkankan-utils-geo-query/src/main/java/com/fdkankan/geo/GeoTransformUtil.java
  21. 115 0
      4dkankan-utils-geo-query/src/main/java/com/fdkankan/geo/MapTool.java
  22. 31 0
      4dkankan-utils-geo-query/src/main/java/com/fdkankan/geo/Proj4Tool.java
  23. 53 0
      4dkankan-utils-geo-tool/pom.xml
  24. 44 34
      4dkankan-utils-model/src/main/java/com/fdkankan/model/utils/CreateHouseJsonUtil.java
  25. 4 2
      4dkankan-utils-model/src/main/java/com/fdkankan/model/utils/CreateObjUtil.java
  26. 43 39
      4dkankan-utils-model/src/main/java/com/fdkankan/model/utils/FloorPlanUserUtil.java
  27. 2 0
      4dkankan-utils-rabbitmq/src/main/java/com/fdkankan/rabbitmq/bean/BuildSceneCallMessage.java
  28. 3 0
      4dkankan-utils-rabbitmq/src/main/java/com/fdkankan/rabbitmq/bean/BuildSceneResultMqMessage.java
  29. 1 1
      4dkankan-utils-reg/pom.xml
  30. 6 5
      4dkankan-utils-reg/src/main/java/com/fdkankan/reg/RegCodeUtil.java
  31. 4 0
      4dkankan-utils-reg/src/main/java/com/fdkankan/reg/dto/CamRegDto.java
  32. 6 0
      4dkankan-utils-reg/src/main/java/com/fdkankan/reg/dto/CamRegSDto.java
  33. 283 0
      4dkankan-utils-sms/src/main/java/com/fdkankan/sms/SmsServiceHuawei.java
  34. 2 18
      pom.xml

+ 5 - 0
4dkankan-common-utils/src/main/java/com/fdkankan/common/constant/ErrorCode.java

@@ -83,12 +83,17 @@ public enum ErrorCode {
     FAILURE_CODE_3032(3032, "当前相机已被授权,请选择另外相机绑定"),
     FAILURE_CODE_3033(3033, "60秒内不能重复获取验证码"),
 
+
+    FAILURE_CODE_3037(3037, "场景原始数据已过期,无法生成mesh!"),
+
     FAILURE_CODE_4001(4001, "缺少必要文件:%s"),
     FAILURE_CODE_4002(4002, "文件不存在:%s"),
     FAILURE_CODE_4003(4003, "图片大小不能超过:%s"),
     FAILURE_CODE_4004(4004, "此接口仅支持看看和看见相机场景"),
     FAILURE_CODE_4005(4005, "已超出容量,不允许重新上传"),
 
+    FAILURE_CODE_4006(4006, "此相机场景不允许上传至官网"),
+
 
     FAILURE_CODE_5001(5001, "modeldata.json为空"),
     FAILURE_CODE_5002(5002, "order值为空"),

+ 5 - 1
4dkankan-common-utils/src/main/java/com/fdkankan/common/constant/SceneSource.java

@@ -10,9 +10,13 @@ public enum SceneSource {
     ZT(3, "转台"),
     JG(4, "激光"),
     SG(5, "深光"),
+    SX(7, "深巡"),
 
     QJKK(6, "全景看看"),
-    YJHZ(11, "一键换装");
+    YJHZ(11, "一键换装"),
+    E57(57, "E57"),
+
+    INSTA_360(36, "INSTA_360");
 
     private Integer code;
     private String message;

+ 3 - 1
4dkankan-common-web/src/main/java/com/fdkankan/web/response/BaseResponseAdvice.java

@@ -22,7 +22,7 @@ import java.util.Objects;
 @Slf4j
 public class BaseResponseAdvice implements ResponseBodyAdvice<Object> {
 
-    @Value("${language:zh_CN}")
+    @Value("${fdkk.language:zh_CN}")
     private String language;
 
     @Override
@@ -55,6 +55,8 @@ public class BaseResponseAdvice implements ResponseBodyAdvice<Object> {
         }
         if (body instanceof ResultData) {
             return getI18n((ResultData) body);
+        }else if(body instanceof Result){
+            return body;
         } else {
             return getI18n(ResultData.ok(body));
         }

+ 29 - 0
4dkankan-common-web/src/main/java/com/fdkankan/web/util/RSAEncrypt.java

@@ -195,6 +195,35 @@ public class RSAEncrypt {
     }
 
     /**
+     * 从文件中输入流中加载公钥
+     *
+     * @throws Exception 加载公钥时产生的异常
+     */
+    public static String loadPublicKeyByFile() throws Exception {
+        try {
+            InputStream inputStream = Thread.currentThread().getContextClassLoader().getResourceAsStream("key/public.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();
+        } catch (IOException e) {
+            throw new Exception("公钥数据读取错误");
+        } catch (NullPointerException e) {
+            throw new Exception("公钥输入流为空");
+        }
+    }
+
+    /**
      * 从文件中加载私钥
      *
      * @return 是否成功

+ 1 - 1
4dkankan-utils-dxf/pom.xml

@@ -10,7 +10,7 @@
     <modelVersion>4.0.0</modelVersion>
 
     <artifactId>4dkankan-utils-dxf</artifactId>
-    <version>3.0.0-SNAPSHOT</version>
+    <version>4.0.0-SNAPSHOT</version>
     <packaging>jar</packaging>
 
     <properties>

+ 1 - 1
4dkankan-utils-dxf/src/main/java/com/fdkankan/dxf/generate/DxfDocWriter.java

@@ -38,7 +38,7 @@ public class DxfDocWriter implements Closeable {
      */
     public static final String[] DEFAULT_ENTITY_NO_REDUCE_PART = {"LINE", "CIRCLE", "ARC", "TEXT", "MTEXT", "LWPOLYLINE"};
     private List<String> entityNoReducePart = Arrays.asList(DEFAULT_ENTITY_NO_REDUCE_PART);
-    private List<DxfEntity> newDxfEntityList;
+    public List<DxfEntity> newDxfEntityList;
     private long maxMeta;
     private Charset charset;
     private DxfExtent extent;

+ 2 - 2
4dkankan-utils-dxf/src/main/java/com/fdkankan/dxf/generate/model/DxfText.java

@@ -44,11 +44,11 @@ public class DxfText extends BaseDxfEntity {
 	/**
 	 * 文字的高度
 	 */
-	private double high = 0;
+	private double high = 5;
 	/**
 	 * 文字的宽度
 	 */
-	private int width = 1;
+	private int width = 0;
 	/**
 	 * 文字内容
 	 */

+ 16 - 0
4dkankan-utils-dxf/src/main/java/com/fdkankan/dxf/math/MathArcUtil.java

@@ -0,0 +1,16 @@
+package com.fdkankan.dxf.math;
+
+public class MathArcUtil {
+
+    // 根据圆的参数方程和圆上一个点的坐标,计算该点的角度
+    // r:圆弧半径
+    // (cx,cy):圆弧的中心点
+    // (x,y):圆弧上某点的坐标
+    public static Double calcArcPointAngle(double r, double cx, double cy, double x, double y){
+        double res = Math.acos((x - cx)/r);
+        if (Math.asin((y - cy)/r) < 0){
+            res = -res;
+        }
+        return res / Math.PI * 180;
+    }
+}

+ 87 - 11
4dkankan-utils-dxf/src/main/java/com/fdkankan/dxf/parse/utils/FdJsonToDxfUtil.java

@@ -7,9 +7,16 @@ import com.fdkankan.dxf.fdjson.vo.FdFloorsPanJson;
 import com.fdkankan.dxf.fdjson.vo.FdPoints;
 import com.fdkankan.dxf.fdjson.vo.FdWalls;
 import com.fdkankan.dxf.generate.DxfDocWriter;
+import com.fdkankan.dxf.generate.DxfGenSupport;
 import com.fdkankan.dxf.generate.Vector3;
+import com.fdkankan.dxf.generate.enums.LineWidthEnum;
+import com.fdkankan.dxf.generate.model.DxfArc;
 import com.fdkankan.dxf.generate.model.DxfLine;
+import com.fdkankan.dxf.generate.model.DxfLwPolyLine;
 import com.fdkankan.dxf.generate.model.base.Color;
+import com.fdkankan.dxf.generate.model.base.DxfEntity;
+import com.fdkankan.dxf.generate.model.support.DxfExtent;
+import com.fdkankan.dxf.math.MathArcUtil;
 import com.fdkankan.dxf.parse.ParseDXF;
 import com.fdkankan.dxf.parse.model.entities.GeometricLine;
 import com.fdkankan.dxf.parse.resolver.DxfResolver;
@@ -17,6 +24,7 @@ import com.fdkankan.dxf.parse.resolver.DxfResolver;
 import java.io.IOException;
 import java.nio.file.Files;
 import java.nio.file.Paths;
+import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.HashSet;
 import java.util.List;
@@ -31,15 +39,17 @@ public class FdJsonToDxfUtil {
      */
     public static void fdJsonToDxf(String fdJsonPath,String dxfPath,Integer subgroup)  {
         try {
+            DxfDocWriter dxfDocWriter = new DxfDocWriter();
             String msg = new String(Files.readAllBytes(Paths.get(fdJsonPath)));
             JSONObject jsonObject = JSONObject.parseObject(msg);
             JSONArray floors = jsonObject.getJSONArray("floors");
             for (Object obj : floors) {
                 JSONObject floor = (JSONObject) (obj);
                 if(floor.getInteger("subgroup") != null && floor.getInteger("subgroup").equals(subgroup)){
-                    plantWall(dxfPath,floor);
+                    plantWall(dxfPath,dxfDocWriter,floor);
                 }
             }
+            dxfDocWriter.save(dxfPath, true);
         }catch (Exception e){
             e.printStackTrace();
         }
@@ -53,13 +63,18 @@ public class FdJsonToDxfUtil {
      */
     public static void fdJsonToDxf(String fdJsonPath,String dxfPath)  {
         try {
+            DxfDocWriter dxfDocWriter = new DxfDocWriter();
+
             String msg = new String(Files.readAllBytes(Paths.get(fdJsonPath)));
             JSONObject jsonObject = JSONObject.parseObject(msg);
             JSONArray floors = jsonObject.getJSONArray("floors");
             for (Object obj : floors) {
                 JSONObject floor = (JSONObject) (obj);
-                plantWall(dxfPath,floor);
+                plantWall(dxfPath,dxfDocWriter,floor);
+                plantSymbols(dxfPath,dxfDocWriter,floor);
+                planFurnitures(dxfPath,dxfDocWriter,floor);
             }
+            dxfDocWriter.save(dxfPath, true);
         }catch (Exception e){
             e.printStackTrace();
         }
@@ -69,7 +84,7 @@ public class FdJsonToDxfUtil {
     /**
      * 墙,根据起始点画线
      */
-    private static void plantWall(String filePath, JSONObject fools) {
+    private static void plantWall(String filePath, DxfDocWriter dxfDocWriter,JSONObject fools) {
         HashMap<String, FdPoints> wallMap= new HashMap<>();
 
         JSONObject walls = fools.getJSONObject("walls");
@@ -79,28 +94,89 @@ public class FdJsonToDxfUtil {
             FdPoints point = new FdPoints(obj.getDouble("x") * 100, obj.getDouble("y") * 100);
             wallMap.put(key,point);
         }
-        DxfDocWriter dxfDocWriter = new DxfDocWriter();
+
         for (String key : walls.keySet()) {
             JSONObject wall = walls.getJSONObject(key);
             String start = wall.getString("start");
             String end = wall.getString("end");
-            drawLinePoint(filePath,wallMap.get(start),wallMap.get(end),dxfDocWriter);
+            Boolean out = wall.getBoolean("out");
+            drawLinePoint(filePath,wallMap.get(start),wallMap.get(end),dxfDocWriter,out);
+        }
+
+    }
+    /**
+     * 门,根据起始点画线
+     */
+    private static void plantSymbols(String filePath,DxfDocWriter dxfDocWriter, JSONObject fools) {
+        JSONObject symbols = fools.getJSONObject("symbols");
+        for (String key : symbols.keySet()) {
+            JSONArray points2d = symbols.getJSONObject(key).getJSONArray("points2d");
+            String openSide = symbols.getJSONObject(key).getString("openSide");
+            drawDoor(points2d, openSide.equals("LEFT"),dxfDocWriter);
+        }
+    }
+
+    private static void planFurnitures(String filePath,DxfDocWriter dxfDocWriter, JSONObject fools) {
+        JSONObject furnitures = fools.getJSONObject("furnitures");
+        for (String key : furnitures.keySet()) {
+            JSONObject obj = furnitures.getJSONObject(key);
+            String furnKey = obj.getString("geoType");
+            JSONObject center = obj.getJSONObject("center");
+
+            Double x = center.getDouble("x") * 100;
+            Double y = center.getDouble("y") * 100;
         }
-        dxfDocWriter.save(filePath, true);
+
     }
 
-    public static void drawLinePoint(String filePath,FdPoints point,FdPoints point2,DxfDocWriter dxfDocWriter){
 
+    public static void drawLinePoint(String filePath,FdPoints point,FdPoints point2,DxfDocWriter dxfDocWriter,Boolean out){
         DxfLine dxfLine = new DxfLine();
         dxfLine.setStartPoint(new Vector3(point.getX(), point.getY(), 0));
         dxfLine.setEndPoint(new Vector3(point2.getX(), point2.getY(), 0));
-        dxfLine.setColor(Color.GREEN);
+        dxfLine.setColor(new Color(0, 180, 64));
+        if(out){
+            dxfLine.setColor(new Color(0, 255, 0));
+        }
         dxfDocWriter.addEntity(dxfLine);
+    }
 
-
+    public static void drawLinePoint(Vector3 point,Vector3 point2,DxfDocWriter dxfDocWriter){
+        DxfLine dxfLine = new DxfLine();
+        dxfLine.setStartPoint(new Vector3(point.getX(), point.getY(), 0));
+        dxfLine.setEndPoint(new Vector3(point2.getX(), point2.getY(), 0));
+        dxfLine.setColor(new Color(0, 120, 32));
+        dxfDocWriter.addEntity(dxfLine);
     }
 
+    public static void drawArc(Vector3 point,Vector3 point2,DxfDocWriter dxfDocWriter,Boolean isLeft){
+        DxfArc dxfArc = new DxfArc();
+        dxfArc.setCenter(point);
+        dxfArc.setColor(Color.green);
+        //勾股定理
+        Double a = Math.abs(point.getX() - point2.getX()) * Math.abs(point.getX() - point2.getX());
+        Double b = Math.abs(point.getY() - point2.getY()) * Math.abs(point.getY() - point2.getY());
+        dxfArc.setRadius(Math.sqrt(a + b));
+        //角度
+        Double atan = Math.atan((point2.getY()-point.getY()) / (point2.getX()-point.getX())) / 3.14 * 180;
+        dxfArc.setStartAngle(atan);
+        dxfArc.setEndAngle(atan + 90);
+        if(isLeft){
+            dxfArc.setStartAngle(atan + 90);
+            dxfArc.setEndAngle(-(180 - atan));
+        }
+        dxfDocWriter.addEntity(dxfArc);
+    }
 
+    public static void drawDoor(JSONArray points2d,Boolean isLeft,DxfDocWriter dxfDocWriter){
+        List<Vector3> vector3List  = new ArrayList<>();
+        for (Object object : points2d) {
+            JSONObject jso = (JSONObject) object;
+            vector3List.add( new Vector3(jso.getDouble("x") * 100,jso.getDouble("y") * 100,jso.getDouble("z")==null?0:jso.getDouble("z") * 100));
+        }
+        drawLinePoint(vector3List.get(0),vector3List.get(3),dxfDocWriter);
+        drawArc(vector3List.get(0),vector3List.get(3),dxfDocWriter,isLeft);
+    }
 
 
     /**
@@ -156,8 +232,8 @@ public class FdJsonToDxfUtil {
     }
 
     public static void main(String[] args) {
-        String inPath ="D:\\cad\\work\\111\\floorplan.json";
-        String outPath ="D:\\cad\\work\\111\\test1.dxf";
+        String inPath ="D:\\cad\\work\\111\\1.json";
+        String outPath ="D:\\cad\\work\\111\\1.dxf";
         FdJsonToDxfUtil.fdJsonToDxf(inPath,outPath);
     }
 }

+ 170 - 0
4dkankan-utils-dxf/src/main/java/com/fdkankan/dxf/parse/utils/LaserMeterToDxfUtil.java

@@ -0,0 +1,170 @@
+package com.fdkankan.dxf.parse.utils;
+
+import cn.hutool.core.date.DateUtil;
+import cn.hutool.core.io.FileUtil;
+import com.alibaba.fastjson.JSONArray;
+import com.alibaba.fastjson.JSONObject;
+import com.fdkankan.dxf.fdjson.vo.FdPoints;
+import com.fdkankan.dxf.generate.DxfDocWriter;
+import com.fdkankan.dxf.generate.Vector3;
+import com.fdkankan.dxf.generate.enums.LineWidthEnum;
+import com.fdkankan.dxf.generate.model.DxfArc;
+import com.fdkankan.dxf.generate.model.DxfLine;
+import com.fdkankan.dxf.generate.model.DxfPoint;
+import com.fdkankan.dxf.generate.model.DxfText;
+import com.fdkankan.dxf.generate.model.base.Color;
+
+import java.io.File;
+import java.math.BigDecimal;
+import java.math.RoundingMode;
+import java.nio.charset.StandardCharsets;
+import java.nio.file.Files;
+import java.nio.file.Paths;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.HashSet;
+
+public class LaserMeterToDxfUtil {
+
+    /**
+     * 场景测量数据转换dxf
+     * @param inFile  json输入文件
+     * @param outPath dxf输出地址
+     */
+
+    public static void toDxf(File inFile, String outPath) throws Exception{
+        String msg = FileUtil.readString(inFile, StandardCharsets.UTF_8);
+        JSONArray jsonObject = JSONArray.parseArray(msg);
+        toDxf(jsonObject,outPath);
+    }
+    public static void toDxf(String inPath, String outPath) throws Exception {
+        JSONArray jsonObject = JSONArray.parseArray(inPath);
+        toDxf(jsonObject,outPath);
+    }
+
+    /**
+     *
+     * @param jsonArray  线数组
+     * @param outPath 输出路径
+     * @throws Exception
+     */
+
+    public static void toDxf(JSONArray jsonArray, String outPath) throws Exception{
+
+        DxfDocWriter dxfDocWriter = new DxfDocWriter();
+        HashSet<Vector3> pointSet= new HashSet<>();
+
+        for (Object obj : jsonArray) {
+            JSONObject jsonObject = (JSONObject) (obj);
+            JSONArray points = jsonObject.getJSONArray("points");
+            String type = jsonObject.getString("type");
+            if(type.contains("AREA") || type.contains("RECTANGLE")){
+                for (int i = 0 ;i < points.size();i ++){
+                    JSONObject point1 = (JSONObject) points.get(i);
+                    JSONObject point2 = (JSONObject) points.get(  i+1 >= points.size()? 0 :i+1 );
+                    drawLine(point1,point2,pointSet,dxfDocWriter);
+                }
+            }
+            if(type.contains("SERIES") ){
+                for (int i = 0 ;i < points.size();i ++){
+                    if(i+1 >= points.size()){
+                        continue;
+                    }
+                    JSONObject point1 = (JSONObject) points.get(i);
+                    JSONObject point2 = (JSONObject) points.get(  i+1 >= points.size()? 0 :i+1 );
+                    drawLine(point1,point2,pointSet,dxfDocWriter);
+                }
+            }
+            if(type.contains("LINE") ){
+                JSONObject point1 = (JSONObject) (points.get(0));
+                JSONObject point2 = (JSONObject) (points.get(1));
+                drawLine(point1,point2,pointSet,dxfDocWriter);
+            }
+
+
+
+        }
+
+        for (Vector3 vector3 : pointSet) {
+            DxfArc dxfArc = new DxfArc();
+            dxfArc.setCenter(vector3);
+            dxfArc.setRadius(0.5);
+            dxfArc.setStartAngle(0);
+            dxfArc.setEndAngle(360);
+            dxfArc.setSolid(true);
+            dxfArc.setSolidColor(new Color(255,255,255));
+            dxfArc.setColor(new Color(255,255,255));
+            dxfDocWriter.addEntity(dxfArc);
+        }
+        dxfDocWriter.save(outPath, true);
+
+    }
+
+
+    /**
+     * 透视投影 模拟人眼视角,将三维点投影到二维平面,常用于计算机图形学。公式为:
+     * x1 = x/z ,y1=y/z
+     *
+     * 正交投影 忽略z
+     */
+    public static void drawLine(JSONObject point1, JSONObject point2, HashSet<Vector3> pointSet,DxfDocWriter dxfDocWriter){
+        Vector3 point3d1 = new Vector3(point1.getDouble("x"),point1.getDouble("y"),point1.getDouble("z"));
+        Vector3 point3d2 = new Vector3(point2.getDouble("x"),point2.getDouble("y"),point2.getDouble("z"));
+        Vector3 startPoint = new Vector3((point1.getDouble("x") ) * 100 ,(point1.getDouble("y")) * 100,0);
+        Vector3 endPoint = new Vector3((point2.getDouble("x") ) * 100 ,(point2.getDouble("y")) * 100,0);
+        pointSet.add(startPoint);
+        pointSet.add(endPoint);
+        drawLinePoint(startPoint,endPoint,dxfDocWriter);
+        BigDecimal bigDecimal = BigDecimal.valueOf(distanceTo(point3d1, point3d2) * 100).setScale(5, RoundingMode.UP);
+        int d = bigDecimal.divide(new BigDecimal(100),2, RoundingMode.UP).intValue();
+        DxfText dxfText = new DxfText();
+        Vector3 vector3 = new Vector3((endPoint.getX() + startPoint.getX()) /2 ,
+                (endPoint.getY() + startPoint.getY() )/2 ,
+                0);
+        dxfText.setStartPoint(vector3);
+        dxfText.setText(bigDecimal.toString()+"cm");
+        dxfText.setAngle(angleBetween(startPoint,endPoint));
+        dxfText.setHigh(d *2);
+        dxfText.setColor(new Color(255,255,255));
+        dxfDocWriter.addEntity(dxfText);
+    }
+
+    public static void drawLinePoint(Vector3 point,Vector3 point2,DxfDocWriter dxfDocWriter){
+        DxfLine dxfLine = new DxfLine();
+        dxfLine.setStartPoint(new Vector3(point.getX(), point.getY(), 0));
+        dxfLine.setEndPoint(new Vector3(point2.getX(), point2.getY(), 0));
+        dxfLine.setColor(new Color(255,255,255));
+        dxfDocWriter.addEntity(dxfLine);
+    }
+
+
+    // 计算两点之间的角度(相对于水平轴,单位为弧度)
+    public static double angleBetween(Vector3 point, Vector3 point2) {
+        //角度
+        Double atan = Math.atan((point2.getY()-point.getY()) / (point2.getX()-point.getX())) / 3.14 * 180;
+        return atan;
+    }
+
+    // 计算两点之间的线段长度
+    public static double distanceBetween(Vector3 p1, Vector3 p2) {
+        double deltaX = p2.getX() - p1.getX();
+        double deltaY = p2.getY() - p1.getY();
+        return Math.sqrt(deltaX * deltaX + deltaY * deltaY);
+    }
+
+    // 计算两点之间的距离
+    public static double distanceTo(Vector3 p1, Vector3 p2) {
+        double dx = p1.getX() - p2.getX();
+        double dy = p1.getY() - p2.getY();
+        double dz = p1.getZ() - p2.getZ();
+        return Math.sqrt(dx * dx + dy * dy + dz * dz);
+    }
+
+    public static void main(String[] args) throws Exception{
+        String inPath ="D:\\cad\\work\\111\\1.json";
+        String outPath ="D:\\cad\\work\\111\\"+new Date().getTime()+".dxf";
+        LaserMeterToDxfUtil.toDxf(new File(inPath),outPath);
+    }
+
+
+}

+ 4 - 0
4dkankan-utils-filestorage/src/main/java/com/fdkankan/filestorage/FileStorageTemplate.java

@@ -7,6 +7,7 @@ import org.springframework.stereotype.Service;
 import java.io.File;
 import java.io.IOException;
 import java.io.InputStream;
+import java.net.URL;
 import java.util.List;
 import java.util.Map;
 
@@ -108,4 +109,7 @@ public interface FileStorageTemplate {
     String getInternalEndpoint(String bucket ,String key);
     String getInternalEndpoint(String key);
 
+    public URL getPresignedUrl(String bucket, String key);
+    public URL getPresignedUrl( String key);
+
 }

+ 22 - 0
4dkankan-utils-filestorage/src/main/java/com/fdkankan/filestorage/aliyun/AliyunOssTemplate.java

@@ -5,6 +5,7 @@ import cn.hutool.core.io.FileUtil;
 import cn.hutool.core.util.ObjectUtil;
 import cn.hutool.core.util.StrUtil;
 import com.alibaba.fastjson2.JSON;
+import com.aliyun.oss.HttpMethod;
 import com.aliyun.oss.OSS;
 import com.aliyun.oss.ServiceException;
 import com.aliyun.oss.model.*;
@@ -12,6 +13,7 @@ import com.fdkankan.filestorage.Consumer;
 import com.fdkankan.filestorage.InnerUtils;
 import com.fdkankan.filestorage.FileStorageTemplate;
 import com.fdkankan.filestorage.properties.AliyunOssProperties;
+import com.fdkankan.filestorage.util.DomainUtil;
 import lombok.Getter;
 import lombok.SneakyThrows;
 import lombok.extern.slf4j.Slf4j;
@@ -23,12 +25,16 @@ import org.springframework.util.ObjectUtils;
 import org.springframework.util.StringUtils;
 
 import java.io.*;
+import java.net.MalformedURLException;
 import java.net.URI;
+import java.net.URL;
 import java.nio.charset.StandardCharsets;
 import java.util.ArrayList;
 import java.util.List;
 import java.util.Map;
 import java.util.UUID;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
 import java.util.stream.Collectors;
 
 
@@ -456,4 +462,20 @@ public class AliyunOssTemplate implements FileStorageTemplate {
             log.error("列举文件目录失败,key:" + sourcePath, e);
         }
     }
+
+    @Override
+    public URL getPresignedUrl(String bucket, String key) {
+        java.util.Date expiration = new java.util.Date();
+        long expTimeMillis = expiration.getTime();
+        expTimeMillis += 1000 * 60 * 60 * 8;
+        expiration.setTime(expTimeMillis);
+        GeneratePresignedUrlRequest generatePresignedUrlRequest = new GeneratePresignedUrlRequest(bucket, key);
+        generatePresignedUrlRequest.setMethod(HttpMethod.PUT);
+        generatePresignedUrlRequest.setExpiration(expiration);
+        return ossClient.generatePresignedUrl(generatePresignedUrlRequest);
+    }
+    @Override
+    public URL getPresignedUrl(String key) {
+        return getPresignedUrl(ossProperties.getBucket(), key);
+    }
 }

+ 19 - 0
4dkankan-utils-filestorage/src/main/java/com/fdkankan/filestorage/aws/AwsTemplate.java

@@ -8,6 +8,7 @@ import cn.hutool.core.util.ObjectUtil;
 import cn.hutool.core.util.StrUtil;
 import com.alibaba.fastjson2.JSON;
 import com.amazonaws.AmazonServiceException;
+import com.amazonaws.HttpMethod;
 import com.amazonaws.SdkClientException;
 import com.amazonaws.services.s3.AmazonS3;
 import com.amazonaws.services.s3.model.*;
@@ -15,6 +16,7 @@ import com.fdkankan.filestorage.Consumer;
 import com.fdkankan.filestorage.InnerUtils;
 import com.fdkankan.filestorage.FileStorageTemplate;
 import com.fdkankan.filestorage.properties.AwsProperties;
+import com.fdkankan.filestorage.util.DomainUtil;
 import lombok.Getter;
 import lombok.SneakyThrows;
 import lombok.extern.slf4j.Slf4j;
@@ -24,7 +26,9 @@ import org.springframework.util.Base64Utils;
 import org.springframework.util.ObjectUtils;
 
 import java.io.*;
+import java.net.MalformedURLException;
 import java.net.URI;
+import java.net.URL;
 import java.nio.charset.StandardCharsets;
 import java.util.ArrayList;
 import java.util.List;
@@ -527,4 +531,19 @@ public class AwsTemplate implements FileStorageTemplate {
             log.error("列举文件目录失败,key:" + sourcePath, e);
         }
     }
+
+    @Override
+    public URL getPresignedUrl(String bucket, String key) {
+        java.util.Date expiration = new java.util.Date();
+        long expTimeMillis = expiration.getTime();
+        expTimeMillis += 1000 * 60 * 60 * 8;
+        expiration.setTime(expTimeMillis);
+        GeneratePresignedUrlRequest generatePresignedUrlRequest = new GeneratePresignedUrlRequest(bucket, key)
+                .withMethod(HttpMethod.PUT).withExpiration(expiration);
+        return amazonS3Client.generatePresignedUrl(generatePresignedUrlRequest);
+    }
+    @Override
+    public URL getPresignedUrl(String key) {
+        return getPresignedUrl(awsProperties.getBucket(), key);
+    }
 }

+ 19 - 0
4dkankan-utils-filestorage/src/main/java/com/fdkankan/filestorage/cos/CosTemplate.java

@@ -10,6 +10,7 @@ import com.fdkankan.filestorage.InnerUtils;
 import com.fdkankan.filestorage.FileStorageTemplate;
 import com.fdkankan.filestorage.properties.CosProperties;
 import com.qcloud.cos.COSClient;
+import com.qcloud.cos.http.HttpMethodName;
 import com.qcloud.cos.model.*;
 import lombok.Getter;
 import lombok.SneakyThrows;
@@ -22,6 +23,7 @@ import org.springframework.util.ObjectUtils;
 
 import java.io.*;
 import java.net.URI;
+import java.net.URL;
 import java.nio.charset.StandardCharsets;
 import java.util.ArrayList;
 import java.util.List;
@@ -477,4 +479,21 @@ public class CosTemplate implements FileStorageTemplate {
             log.error("列举文件目录失败,key:" + sourcePath, e);
         }
     }
+
+    @Override
+    public URL getPresignedUrl(String bucket, String key) {
+        java.util.Date expiration = new java.util.Date();
+        long expTimeMillis = expiration.getTime();
+        expTimeMillis += 1000 * 60 * 60 * 8;
+        expiration.setTime(expTimeMillis);
+        GeneratePresignedUrlRequest generatePresignedUrlRequest = new GeneratePresignedUrlRequest(bucket, key);
+        generatePresignedUrlRequest.setMethod(HttpMethodName.PUT);
+        generatePresignedUrlRequest.setExpiration(expiration);
+        return cosClient.generatePresignedUrl(generatePresignedUrlRequest);
+    }
+
+    @Override
+    public URL getPresignedUrl(String key) {
+        return getPresignedUrl(cosProperties.getBucket(), key);
+    }
 }

+ 28 - 0
4dkankan-utils-filestorage/src/main/java/com/fdkankan/filestorage/minio/MinioTemplate.java

@@ -5,6 +5,7 @@ import cn.hutool.core.io.FileUtil;
 import cn.hutool.core.io.IoUtil;
 import cn.hutool.core.util.StrUtil;
 import com.alibaba.fastjson2.JSON;
+import com.aliyun.oss.HttpMethod;
 import com.amazonaws.services.s3.model.GetObjectRequest;
 import com.amazonaws.services.s3.model.S3Object;
 import com.amazonaws.services.s3.model.S3ObjectInputStream;
@@ -13,9 +14,12 @@ import com.fdkankan.filestorage.InnerUtils;
 import com.fdkankan.filestorage.properties.MinioProperties;
 
 import com.fdkankan.filestorage.FileStorageTemplate;
+import com.qcloud.cos.http.HttpMethodName;
 import com.qcloud.cos.model.COSObject;
+import com.qcloud.cos.model.GeneratePresignedUrlRequest;
 import io.minio.*;
 import io.minio.errors.*;
+import io.minio.http.Method;
 import io.minio.messages.Item;
 import lombok.Getter;
 import lombok.SneakyThrows;
@@ -27,8 +31,12 @@ import org.springframework.util.ObjectUtils;
 
 import java.io.*;
 import java.net.URI;
+import java.net.URL;
 import java.nio.charset.StandardCharsets;
+import java.security.InvalidKeyException;
+import java.security.NoSuchAlgorithmException;
 import java.util.*;
+import java.util.concurrent.TimeUnit;
 
 /**
  * 阿里云操作模版类, 简化常见操作
@@ -520,4 +528,24 @@ public class MinioTemplate implements FileStorageTemplate {
             log.error("列举文件目录失败,key:" + sourcePath, e);
         }
     }
+
+    @Override
+    public URL getPresignedUrl(String bucket, String key) {
+        GetPresignedObjectUrlArgs build = GetPresignedObjectUrlArgs.builder()
+                .method(Method.PUT)
+                .bucket(bucket)
+                .object(key)
+                .expiry(8, TimeUnit.HOURS) //过期时间
+                //.extraQueryParams(reqParams)
+                .build();
+        try {
+            return new URL(minioClient.getPresignedObjectUrl(build));
+        } catch (Exception e) {
+            throw new RuntimeException(e);
+        }
+    }
+    @Override
+    public URL getPresignedUrl(String key) {
+        return getPresignedUrl(minioProperties.getBucket(), key);
+    }
 }

+ 45 - 0
4dkankan-utils-filestorage/src/main/java/com/fdkankan/filestorage/util/DomainUtil.java

@@ -0,0 +1,45 @@
+package com.fdkankan.filestorage.util;
+
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+/**
+ * @author Xiewj
+ * @date 2025/3/11
+ */
+public class DomainUtil {
+    // 定义一个方法用于替换文本中的域名
+    public static String replaceDomain(String url, String newDomain) {
+        // 正则表达式用于匹配URL中的域名部分(包括可能的协议部分)
+        String patternString = "(https?://)[\\w.-]+";
+        Pattern pattern = Pattern.compile(patternString);
+        Matcher matcher = pattern.matcher(url);
+
+        // 使用新域名进行替换
+        StringBuffer result = new StringBuffer();
+        while (matcher.find()) {
+            // 检查新域名是否已包含协议
+            if (newDomain.startsWith("http://") || newDomain.startsWith("https://")) {
+                // 如果新域名已经包含协议,则直接替换整个匹配的部分
+                matcher.appendReplacement(result, newDomain);
+            } else {
+                // 如果新域名不包含协议,则仅替换域名部分
+                matcher.appendReplacement(result, matcher.group(1) + newDomain);
+            }
+        }
+        matcher.appendTail(result);
+
+        return result.toString();
+    }
+
+    public static void main(String[] args) {
+        // 测试用例
+        String originalUrl = "https://laser-data.oss-cn-shenzhen.aliyuncs.com/testdata/SG-t-nlpWGOCYxCT/temp/model/1899294769733570560.ply?Expires=1741690934&OSSAccessKeyId=LTAI5tJwboCj3r4vUNkSmbyX&Signature=7PdIUcsuJhNwSVbMX0RpWEVcpqk%3D";
+        String newDomainWithProtocol = "https://aaa.bbb.com"; // 新域名包含协议
+        System.out.println("原始URL: " + originalUrl);
+
+        // 替换域名后的URL
+        String replacedUrl = replaceDomain(originalUrl, newDomainWithProtocol);
+        System.out.println("替换后的URL: " + replacedUrl);
+    }
+}

+ 35 - 4
4dkankan-utils-fyun-oss/src/main/java/com/fdkankan/fyun/oss/OssFileService.java

@@ -1,9 +1,13 @@
 package com.fdkankan.fyun.oss;
 
 import cn.hutool.core.collection.CollUtil;
+import com.alibaba.fastjson.JSON;
 import com.aliyun.oss.HttpMethod;
 import com.aliyun.oss.OSS;
+import com.aliyun.oss.OSSClientBuilder;
+import com.aliyun.oss.common.comm.ResponseMessage;
 import com.aliyun.oss.model.*;
+import com.fdkankan.common.util.FileMd5Util;
 import com.fdkankan.fyun.constant.FYunTypeEnum;
 import com.fdkankan.fyun.face.AbstractFYunFileService;
 import org.slf4j.Logger;
@@ -18,9 +22,7 @@ import org.springframework.util.StringUtils;
 import java.io.*;
 import java.math.BigDecimal;
 import java.net.URL;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Map;
+import java.util.*;
 import java.util.stream.Collectors;
 
 @Component
@@ -81,7 +83,7 @@ public class OssFileService extends AbstractFYunFileService {
                     metadata.setHeader(header.getKey(), header.getValue());
                 }
             }
-            ossClient.putObject(bucket, remoteFilePath, file, metadata);
+            PutObjectResult putObjectResult = ossClient.putObject(bucket, remoteFilePath, file, metadata);
             log.info("文件上传成功,path:{}", filePath);
         } catch (Exception e) {
             log.error("oss上传文件失败,filePath:"+filePath, e);
@@ -89,6 +91,35 @@ public class OssFileService extends AbstractFYunFileService {
         return null;
     }
 
+    public static void main(String[] args) {
+        File file = new File("D:\\Downloads\\SG-t-GjwsdgpLvDb\\wwwroot\\scene_view_data\\SG-t-GjwsdgpLvDb\\images\\pan\\high\\0.jpg");
+        String fileMD5 = FileMd5Util.getFileMD5(file);
+        System.out.println("本地文件md5:" + fileMD5);
+        ObjectMetadata metadata = new ObjectMetadata();
+        Map<String, String> tags = new HashMap<>();
+        tags.put("tag-a", file.getName());
+        metadata.setObjectTagging(tags);
+        OSS ossClient = new OSSClientBuilder().build("http://oss-cn-shenzhen.aliyuncs.com", "LTAI5tJwboCj3r4vUNkSmbyX", "meDy7VYAWbg8kZCKsoUZcIYQxigWOy");
+        PutObjectRequest request = new PutObjectRequest("4dkankan", "testdata/0.jpg", file, metadata);
+        request.setVersionId("123444");
+        PutObjectResult putObjectResult = ossClient.putObject(request);
+        String requestId = putObjectResult.getRequestId();
+        System.out.println("requestId:" + requestId);
+        System.out.println(System.currentTimeMillis());
+        boolean exist = ossClient.doesObjectExist("4dkankan", "testdata/0.jpg");
+        System.out.println(System.currentTimeMillis());
+        System.out.println("文件是否存在:" + exist);
+        if(!exist){
+            System.out.println("文件不存在");
+            // TODO: 2025/3/31 失败处理
+        }
+
+        putObjectResult.getVersionId();
+        System.out.println(putObjectResult.getVersionId());
+
+//        System.out.println(requestId1.equals(requestId2));
+    }
+
     @Override
     public String uploadFileByCommand(String bucket, String filePath, String remoteFilePath) {
         try {

+ 6 - 1
4dkankan-utils-geo-query/pom.xml

@@ -14,6 +14,7 @@
     <properties>
         <fastjson.version>2.0.6</fastjson.version>
         <hutool.version>5.8.6</hutool.version>
+        <proj4j.version>1.1.4</proj4j.version>
     </properties>
 
     <dependencies>
@@ -46,7 +47,11 @@
             <version>2.3.12.RELEASE</version>
         </dependency>
 
-
+        <dependency>
+            <groupId>org.locationtech.proj4j</groupId>
+            <artifactId>proj4j</artifactId>
+            <version>${proj4j.version}</version>
+        </dependency>
     </dependencies>
 
 </project>

+ 2 - 2
4dkankan-utils-geo-query/src/main/java/com/fdkankan/geo/GeoQueryUtil.java

@@ -41,10 +41,10 @@ import java.nio.file.StandardCopyOption;
 @ConfigurationProperties(prefix = "geoquery")
 public class GeoQueryUtil {
     @Value("${geoquery.dataFilePath:/mnt/geoQuery/GeoJSON.json}")
-    private String dataFilePath;
+    private String dataFilePath="I:\\geoserver\\AreaCity-Query-Geometry\\GeoJSON-Polygon-ok_geo-240508-162233";
 
     @Value("${geoquery.saveWkbsFilePath:/mnt/geoQuery/GeoJSON.wkbs}")
-    private String saveWkbsFilePath;
+    private String saveWkbsFilePath="I:\\geoserver\\AreaCity-Query-Geometry\\GeoJSON.wkbs";
 
     @PostConstruct
     public void init() {

+ 53 - 0
4dkankan-utils-geo-query/src/main/java/com/fdkankan/geo/GeoTransformUtil.java

@@ -0,0 +1,53 @@
+package com.fdkankan.geo;
+
+import org.locationtech.proj4j.*;
+
+/**
+ * @author Xiewj
+ * @date 2024/12/31
+ */
+public class GeoTransformUtil {
+
+    static String wgs84CRS = "4326";
+
+    /**
+     * 获取wgs84坐标
+     *
+     * @param sourceCRS   原始坐标系代码 EPSG:3857; 只需要EPSG冒号后的编码
+     * @param coordinate   new ProjCoordinate(lon, lat) 坐标系代码   原始数据坐标系 "4326";  "EPSG:3857";
+     * @return
+     */
+    public static Double[] getWgs84(ProjCoordinate coordinate, String sourceCRS) {
+        ProjCoordinate projCoordinate = Proj4Tool.convertByTargetCRS(coordinate, sourceCRS, wgs84CRS);
+        return new Double[]{projCoordinate.x,projCoordinate.y,coordinate.z};
+    }
+    /**
+     * 获取高德坐标系  wgs84ToGcj02
+     * 即wgs84 转 高德
+     * @param coordinate   new ProjCoordinate(lon, lat) 坐标系代码   wgs84坐标系
+     * @return
+     */
+    public static Double[] wgs84ToGcj02(ProjCoordinate coordinate) {
+        Double[] doubles = MapTool.WGS84ToGCJ02(coordinate.x, coordinate.y);
+        return new Double[]{doubles[0],doubles[1],coordinate.z};
+    }
+    /**
+     * 获取百度坐标系  gcj02ToBd09
+     * 即高德 转 百度
+     * @param coordinate   new ProjCoordinate(lon, lat) 坐标系代码   wgs84坐标系
+     * @return
+     */
+    public static Double[] gcj02ToBd09(ProjCoordinate coordinate) {
+        Double[] doubles = MapTool.GCJ02ToBD09(coordinate.x, coordinate.y);
+        return new Double[]{doubles[0],doubles[1],coordinate.z};
+    }
+
+    public static void main(String[] args) {
+        ProjCoordinate coordinate1 = new ProjCoordinate(454938.2,2476768.45,46.8);
+        Double[] wgs84 = getWgs84(coordinate1, "4547");
+        System.out.println("wgs84:"+wgs84[0]+","+wgs84[1]+","+wgs84[2]);
+        ProjCoordinate coordinate2 = new ProjCoordinate(wgs84[0],wgs84[1],wgs84[2]);
+        Double[] gcj02 = wgs84ToGcj02(coordinate2);
+        System.out.println("gcj02:"+gcj02[0]+","+gcj02[1]+","+gcj02[2]);
+    }
+}

+ 115 - 0
4dkankan-utils-geo-query/src/main/java/com/fdkankan/geo/MapTool.java

@@ -0,0 +1,115 @@
+package com.fdkankan.geo;
+
+import cn.hutool.extra.spring.SpringUtil;
+
+/**
+ * @author Xiewj
+ * @date 2024/12/31
+ */
+public class MapTool {
+    private static double x_PI = 3.14159265358979324 * 3000.0 / 180.0;
+    private static double PI = 3.1415926535897932384626;
+    private static double a = 6378245.0;
+    private static double ee = 0.00669342162296594323;
+
+    /**
+     * 百度坐标系 (BD-09) 与 火星坐标系 (GCJ-02)的转换
+     * 即 百度 转 谷歌、高德
+     * @param bd_lon
+     * @param bd_lat
+     * @return Double[lon,lat]
+     */
+    public static Double[] BD09ToGCJ02(Double bd_lon,Double bd_lat){
+        double x = bd_lon - 0.0065;
+        double y = bd_lat - 0.006;
+        double z = Math.sqrt(x * x + y * y) - 0.00002 * Math.sin(y * x_PI);
+        double theta = Math.atan2(y, x) - 0.000003 * Math.cos(x * x_PI);
+        Double[] arr = new Double[2];
+        arr[0] = z * Math.cos(theta);
+        arr[1] = z * Math.sin(theta);
+        return arr;
+    }
+
+    /**
+     * 火星坐标系 (GCJ-02) 与百度坐标系 (BD-09) 的转换
+     * 即谷歌、高德 转 百度
+     * @param gcj_lon
+     * @param gcj_lat
+     * @return Double[lon,lat]
+     */
+    public static Double[] GCJ02ToBD09(Double gcj_lon,Double gcj_lat){
+        double z = Math.sqrt(gcj_lon * gcj_lon + gcj_lat * gcj_lat) + 0.00002 * Math.sin(gcj_lat * x_PI);
+        double theta = Math.atan2(gcj_lat, gcj_lon) + 0.000003 * Math.cos(gcj_lon * x_PI);
+        Double[] arr = new Double[2];
+        arr[0] = z * Math.cos(theta) + 0.0065;
+        arr[1] = z * Math.sin(theta) + 0.006;
+        return arr;
+    }
+
+    /**
+     * WGS84转GCJ02
+     * @param wgs_lon
+     * @param wgs_lat
+     * @return Double[lon,lat]
+     */
+    public static Double[] WGS84ToGCJ02(Double wgs_lon,Double wgs_lat){
+        GeoQueryUtil queryUtil = SpringUtil.getBean(GeoQueryUtil.class);
+        if (!queryUtil.queryPoint(wgs_lon, wgs_lat)) {
+            return new Double[]{wgs_lon,wgs_lat};
+        }
+        double dlat = transformlat(wgs_lon - 105.0, wgs_lat - 35.0);
+        double dlng = transformlng(wgs_lon - 105.0, wgs_lat - 35.0);
+        double radlat = wgs_lat / 180.0 * PI;
+        double magic = Math.sin(radlat);
+        magic = 1 - ee * magic * magic;
+        double sqrtmagic = Math.sqrt(magic);
+        dlat = (dlat * 180.0) / ((a * (1 - ee)) / (magic * sqrtmagic) * PI);
+        dlng = (dlng * 180.0) / (a / sqrtmagic * Math.cos(radlat) * PI);
+        Double[] arr = new Double[2];
+        arr[0] = wgs_lon + dlng;
+        arr[1] = wgs_lat + dlat;
+        return arr;
+    }
+
+    /**
+     * GCJ02转WGS84
+     * @param gcj_lon
+     * @param gcj_lat
+     * @return Double[lon,lat]
+     */
+    public static Double[] GCJ02ToWGS84(Double gcj_lon,Double gcj_lat){
+        GeoQueryUtil queryUtil = SpringUtil.getBean(GeoQueryUtil.class);
+        if (!queryUtil.queryPoint(gcj_lon, gcj_lat)) {
+            return new Double[]{gcj_lon,gcj_lat};
+        }
+        double dlat = transformlat(gcj_lon - 105.0, gcj_lat - 35.0);
+        double dlng = transformlng(gcj_lon - 105.0, gcj_lat - 35.0);
+        double radlat = gcj_lat / 180.0 * PI;
+        double magic = Math.sin(radlat);
+        magic = 1 - ee * magic * magic;
+        double sqrtmagic = Math.sqrt(magic);
+        dlat = (dlat * 180.0) / ((a * (1 - ee)) / (magic * sqrtmagic) * PI);
+        dlng = (dlng * 180.0) / (a / sqrtmagic * Math.cos(radlat) * PI);
+        double mglat = gcj_lat + dlat;
+        double mglng = gcj_lon + dlng;
+        return new Double[]{gcj_lon * 2 - mglng, gcj_lat * 2 - mglat};
+    }
+
+    private static Double transformlat(double lng, double lat) {
+        double ret = -100.0 + 2.0 * lng + 3.0 * lat + 0.2 * lat * lat + 0.1 * lng * lat + 0.2 * Math.sqrt(Math.abs(lng));
+        ret += (20.0 * Math.sin(6.0 * lng * PI) + 20.0 * Math.sin(2.0 * lng * PI)) * 2.0 / 3.0;
+        ret += (20.0 * Math.sin(lat * PI) + 40.0 * Math.sin(lat / 3.0 * PI)) * 2.0 / 3.0;
+        ret += (160.0 * Math.sin(lat / 12.0 * PI) + 320 * Math.sin(lat * PI / 30.0)) * 2.0 / 3.0;
+        return ret;
+    }
+
+    private static Double transformlng(double lng,double lat) {
+        double ret = 300.0 + lng + 2.0 * lat + 0.1 * lng * lng + 0.1 * lng * lat + 0.1 * Math.sqrt(Math.abs(lng));
+        ret += (20.0 * Math.sin(6.0 * lng * PI) + 20.0 * Math.sin(2.0 * lng * PI)) * 2.0 / 3.0;
+        ret += (20.0 * Math.sin(lng * PI) + 40.0 * Math.sin(lng / 3.0 * PI)) * 2.0 / 3.0;
+        ret += (150.0 * Math.sin(lng / 12.0 * PI) + 300.0 * Math.sin(lng / 30.0 * PI)) * 2.0 / 3.0;
+        return ret;
+    }
+
+
+}

+ 31 - 0
4dkankan-utils-geo-query/src/main/java/com/fdkankan/geo/Proj4Tool.java

@@ -0,0 +1,31 @@
+package com.fdkankan.geo;
+
+import org.locationtech.proj4j.*;
+
+/**
+ * @author Xiewj
+ * @date 2024/12/31
+ */
+public class Proj4Tool {
+    /**
+     * proj4的常用坐标转换方法
+     *
+     * @param coordinate 经度或者x轴 纬度或者y轴
+     * @param targetCRS  坐标系代码   原始数据坐标系 "4326";  "EPSG:3857";
+     *                   //     * @param targetCRS   坐标系代码  结果数据坐标系
+     * @return
+     */
+    public static ProjCoordinate convertByTargetCRS(ProjCoordinate coordinate, String sourceCRS, String targetCRS) {
+        CoordinateTransformFactory ctFactory = new CoordinateTransformFactory();
+        CRSFactory csFactory = new CRSFactory();
+
+        CoordinateReferenceSystem crs1 = csFactory.createFromName("EPSG:" + sourceCRS);
+        CoordinateReferenceSystem crs2 = csFactory.createFromName("EPSG:" + targetCRS);
+
+        CoordinateTransform trans = ctFactory.createTransform(crs1, crs2);
+
+        ProjCoordinate p2 = new ProjCoordinate();
+
+        return trans.transform(coordinate, p2);
+    }
+}

+ 53 - 0
4dkankan-utils-geo-tool/pom.xml

@@ -0,0 +1,53 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <parent>
+        <artifactId>4dkankan-utils</artifactId>
+        <groupId>com.fdkankan</groupId>
+        <version>3.0.0-SNAPSHOT</version>
+    </parent>
+    <modelVersion>4.0.0</modelVersion>
+
+    <artifactId>4dkankan-utils-geo-query</artifactId>
+
+    <properties>
+        <fastjson.version>2.0.6</fastjson.version>
+        <hutool.version>5.8.6</hutool.version>
+        <proj4j.version>1.1.4</proj4j.version>
+    </properties>
+
+    <dependencies>
+        <dependency>
+            <groupId>ch.qos.logback</groupId>
+            <artifactId>logback-classic</artifactId>
+            <version>1.2.11</version>
+        </dependency>
+        <!-- 阿里JSON解析器 -->
+        <dependency>
+            <groupId>com.alibaba.fastjson2</groupId>
+            <artifactId>fastjson2</artifactId>
+            <version>${fastjson.version}</version>
+        </dependency>
+
+        <dependency>
+            <groupId>cn.hutool</groupId>
+            <artifactId>hutool-all</artifactId>
+            <version>${hutool.version}</version>
+        </dependency>
+
+        <dependency>
+            <groupId>org.locationtech.proj4j</groupId>
+            <artifactId>proj4j</artifactId>
+            <version>${proj4j.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-autoconfigure</artifactId>
+            <version>2.3.12.RELEASE</version>
+        </dependency>
+
+
+    </dependencies>
+
+</project>

+ 44 - 34
4dkankan-utils-model/src/main/java/com/fdkankan/model/utils/CreateHouseJsonUtil.java

@@ -95,19 +95,22 @@ public class CreateHouseJsonUtil {
 		Map<String, PointBean> pointMap = new HashMap<>();
 		Map<Integer, String> vpMap = new HashMap<>();
 		JSONArray vertexArr = floor.getJSONArray("vertex-xy");
-		for(int i = 0; i < vertexArr.size(); i++){
-			Object o = vertexArr.get(i);
+		if(CollUtil.isNotEmpty(vertexArr)){
+			for(int i = 0; i < vertexArr.size(); i++){
+				Object o = vertexArr.get(i);
 
-			VertexBean vertexBean = JSON.parseObject(JSON.toJSONString(o), VertexBean.class);
-			Integer vertexId = vertexBean.getId();
-			vertexMap.put(vertexId, vertexBean);
+				VertexBean vertexBean = JSON.parseObject(JSON.toJSONString(o), VertexBean.class);
+				Integer vertexId = vertexBean.getId();
+				vertexMap.put(vertexId, vertexBean);
 
-			String pointId = "Point" + i;
-			pointMap.put(pointId, PointBean.builder().vectorId(pointId).x(vertexBean.getX()).y(vertexBean.getY()).build());
+				String pointId = "Point" + i;
+				pointMap.put(pointId, PointBean.builder().vectorId(pointId).x(vertexBean.getX()).y(vertexBean.getY()).build());
 
-			vpMap.put(vertexId, pointId);
+				vpMap.put(vertexId, pointId);
+			}
 		}
 
+
 		//处理墙
 		Map<Integer, SegmentBean> segmentMap = new HashMap<>();
 		Map<String, WallBean> wallMap = new HashMap<>();
@@ -115,32 +118,34 @@ public class CreateHouseJsonUtil {
 		JSONArray segmentArr = floor.getJSONArray("segment");
 		Map<String, String> startMap = new HashMap<>();
 		Map<String, String> endMap = new HashMap<>();
-		for(int i = 0; i < segmentArr.size(); i++){
-			Object o = segmentArr.get(i);
-
-			SegmentBean segmentBean = JSON.parseObject(JSON.toJSONString(o), SegmentBean.class);
-			String startPointId = vpMap.get(segmentBean.getA());
-			String endPointId = vpMap.get(segmentBean.getB());
-			segmentBean.setStartPointId(startPointId);
-			segmentBean.setEndPointId(endPointId);
-
-			Integer segmentId = segmentBean.getId();
-			segmentMap.put(segmentId, segmentBean);
-
-			String wallId = "Wall" + i;
-			WallBean wallBean = WallBean.builder()
-				.vectorId(wallId)
-				.start(segmentBean.getStartPointId())
-				.end(segmentBean.getEndPointId())
-				.children(new String[]{})
-				.width(0.2d)
-				.build();
-			wallMap.put(wallId, wallBean);
-
-			startMap.put(wallBean.getStart(), wallBean.getVectorId());
-			endMap.put(wallBean.getEnd(), wallBean.getVectorId());
-
-			swMap.put(segmentId, wallId);
+		if(CollUtil.isNotEmpty(segmentArr)){
+			for(int i = 0; i < segmentArr.size(); i++){
+				Object o = segmentArr.get(i);
+
+				SegmentBean segmentBean = JSON.parseObject(JSON.toJSONString(o), SegmentBean.class);
+				String startPointId = vpMap.get(segmentBean.getA());
+				String endPointId = vpMap.get(segmentBean.getB());
+				segmentBean.setStartPointId(startPointId);
+				segmentBean.setEndPointId(endPointId);
+
+				Integer segmentId = segmentBean.getId();
+				segmentMap.put(segmentId, segmentBean);
+
+				String wallId = "Wall" + i;
+				WallBean wallBean = WallBean.builder()
+						.vectorId(wallId)
+						.start(segmentBean.getStartPointId())
+						.end(segmentBean.getEndPointId())
+						.children(new String[]{})
+						.width(0.2d)
+						.build();
+				wallMap.put(wallId, wallBean);
+
+				startMap.put(wallBean.getStart(), wallBean.getVectorId());
+				endMap.put(wallBean.getEnd(), wallBean.getVectorId());
+
+				swMap.put(segmentId, wallId);
+			}
 		}
 
 		Collection<PointBean> pointBeans = pointMap.values();
@@ -163,6 +168,11 @@ public class CreateHouseJsonUtil {
 
 	}
 
+	public static void main(String[] args) {
+		JSONObject houseTypeJsonByCad = createHouseTypeJsonByCad("D:\\Downloads\\floorplan_cad.json");
+		FileUtil.writeUtf8String(houseTypeJsonByCad.toJSONString(), "D:\\Downloads\\houseType.json");
+	}
+
 	private static JSONObject init() {
 		JSONObject outContent = new JSONObject();
 		outContent.put("name", "houseType.json");

+ 4 - 2
4dkankan-utils-model/src/main/java/com/fdkankan/model/utils/CreateObjUtil.java

@@ -352,8 +352,10 @@ public class CreateObjUtil {
 
 	public static void main(String[] args) throws Exception {
 
-		convertVisionmodeldataToTxt("D:\\test\\test\\vision.modeldata", "D:\\test\\test\\vision.txt");
-		FileUtil.del("D:\\test\\test");
+//		convertVisionmodeldataToTxt("D:\\test\\test\\vision.modeldata", "D:\\test\\test\\vision.txt");
+//		FileUtil.del("D:\\test\\test");
+
+		convertTxtToVisionmodeldata("D:\\test\\vision_100(1).txt", "D:\\test\\vision_100.modeldata");
 
 	}
 

+ 43 - 39
4dkankan-utils-model/src/main/java/com/fdkankan/model/utils/FloorPlanUserUtil.java

@@ -20,8 +20,8 @@ import java.util.Map;
 public class FloorPlanUserUtil {
 
 	public static void main(String[] args) {
-		JSONObject floorPlanUserJson = FloorPlanUserUtil.createFloorPlanUserJson("D:\\test\\新建文件夹\\floorplan_cad.json");
-		FileUtil.writeUtf8String(floorPlanUserJson.toJSONString(), "D:\\test\\新建文件夹\\floorplan.json");
+		JSONObject floorPlanUserJson = FloorPlanUserUtil.createFloorPlanUserJson("D:\\Downloads\\floorplan_cad.json");
+		FileUtil.writeUtf8String(floorPlanUserJson.toJSONString(), "D:\\Downloads\\floorplan.json");
 
 	}
 
@@ -91,18 +91,20 @@ public class FloorPlanUserUtil {
 		Map<String, PointBean> pointMap = new HashMap<>();
 		Map<Integer, String> vpMap = new HashMap<>();
 		JSONArray vertexArr = floor.getJSONArray("vertex-xy");
-		for(int i = 0; i < vertexArr.size(); i++){
-			Object o = vertexArr.get(i);
+		if(CollUtil.isNotEmpty(vertexArr)){
+			for(int i = 0; i < vertexArr.size(); i++){
+				Object o = vertexArr.get(i);
 
-			VertexBean vertexBean = JSON.parseObject(JSON.toJSONString(o), VertexBean.class);
-			Integer vertexId = vertexBean.getId();
-			vertexMap.put(vertexId, vertexBean);
+				VertexBean vertexBean = JSON.parseObject(JSON.toJSONString(o), VertexBean.class);
+				Integer vertexId = vertexBean.getId();
+				vertexMap.put(vertexId, vertexBean);
 
-			String pointId = "Point" + currentId;
-			pointMap.put(pointId, PointBean.builder().geoType("Point").vectorId(pointId).x(vertexBean.getX()).y(vertexBean.getY()).build());
-			++currentId;
+				String pointId = "Point" + currentId;
+				pointMap.put(pointId, PointBean.builder().geoType("Point").vectorId(pointId).x(vertexBean.getX()).y(vertexBean.getY()).build());
+				++currentId;
 
-			vpMap.put(vertexId, pointId);
+				vpMap.put(vertexId, pointId);
+			}
 		}
 
 		//处理墙
@@ -112,34 +114,36 @@ public class FloorPlanUserUtil {
 		JSONArray segmentArr = floor.getJSONArray("segment");
 		Map<String, String> startMap = new HashMap<>();
 		Map<String, String> endMap = new HashMap<>();
-		for(int i = 0; i < segmentArr.size(); i++){
-			Object o = segmentArr.get(i);
-
-			SegmentBean segmentBean = JSON.parseObject(JSON.toJSONString(o), SegmentBean.class);
-			String startPointId = vpMap.get(segmentBean.getA());
-			String endPointId = vpMap.get(segmentBean.getB());
-			segmentBean.setStartPointId(startPointId);
-			segmentBean.setEndPointId(endPointId);
-
-			Integer segmentId = segmentBean.getId();
-			segmentMap.put(segmentId, segmentBean);
-
-			String wallId = "Wall" + currentId;
-			WallBean wallBean = WallBean.builder()
-				.geoType("Wall")
-				.vectorId(wallId)
-				.start(segmentBean.getStartPointId())
-				.end(segmentBean.getEndPointId())
-				.children(new String[]{})
-				.width(0.2d)
-				.build();
-			wallMap.put(wallId, wallBean);
-			++currentId;
-
-			startMap.put(wallBean.getStart(), wallBean.getVectorId());
-			endMap.put(wallBean.getEnd(), wallBean.getVectorId());
-
-			swMap.put(segmentId, wallId);
+		if(CollUtil.isNotEmpty(segmentArr)){
+			for(int i = 0; i < segmentArr.size(); i++){
+				Object o = segmentArr.get(i);
+
+				SegmentBean segmentBean = JSON.parseObject(JSON.toJSONString(o), SegmentBean.class);
+				String startPointId = vpMap.get(segmentBean.getA());
+				String endPointId = vpMap.get(segmentBean.getB());
+				segmentBean.setStartPointId(startPointId);
+				segmentBean.setEndPointId(endPointId);
+
+				Integer segmentId = segmentBean.getId();
+				segmentMap.put(segmentId, segmentBean);
+
+				String wallId = "Wall" + currentId;
+				WallBean wallBean = WallBean.builder()
+						.geoType("Wall")
+						.vectorId(wallId)
+						.start(segmentBean.getStartPointId())
+						.end(segmentBean.getEndPointId())
+						.children(new String[]{})
+						.width(0.2d)
+						.build();
+				wallMap.put(wallId, wallBean);
+				++currentId;
+
+				startMap.put(wallBean.getStart(), wallBean.getVectorId());
+				endMap.put(wallBean.getEnd(), wallBean.getVectorId());
+
+				swMap.put(segmentId, wallId);
+			}
 		}
 
 		Collection<PointBean> pointBeans = pointMap.values();

+ 2 - 0
4dkankan-utils-rabbitmq/src/main/java/com/fdkankan/rabbitmq/bean/BuildSceneCallMessage.java

@@ -3,6 +3,7 @@ package com.fdkankan.rabbitmq.bean;
 import lombok.Data;
 
 import java.util.Date;
+import java.util.LinkedHashMap;
 import java.util.Map;
 
 @Data
@@ -23,4 +24,5 @@ public class BuildSceneCallMessage extends BaseBuildSceneMessage {
     private Map<String,Object> ext;
 
     private String bizType;
+
 }

+ 3 - 0
4dkankan-utils-rabbitmq/src/main/java/com/fdkankan/rabbitmq/bean/BuildSceneResultMqMessage.java

@@ -5,6 +5,7 @@ import lombok.Builder;
 import lombok.Data;
 import lombok.NoArgsConstructor;
 
+import java.util.LinkedHashMap;
 import java.util.Map;
 
 @Data
@@ -24,4 +25,6 @@ public class BuildSceneResultMqMessage extends BaseBuildSceneMessage{
     private Map<String,Object> ext;
 
     private Integer errorType;
+
+    private LinkedHashMap<Integer, Boolean> detFloorplan;
 }

+ 1 - 1
4dkankan-utils-reg/pom.xml

@@ -12,7 +12,7 @@
     <artifactId>4dkankan-utils-reg</artifactId>
 
     <properties>
-        <fastjson.version>2.0.6</fastjson.version>
+        <fastjson.version>2.0.53</fastjson.version>
         <hutool.version>5.8.6</hutool.version>
     </properties>
 

Різницю між файлами не показано, бо вона завелика
+ 6 - 5
4dkankan-utils-reg/src/main/java/com/fdkankan/reg/RegCodeUtil.java


+ 4 - 0
4dkankan-utils-reg/src/main/java/com/fdkankan/reg/dto/CamRegDto.java

@@ -1,5 +1,6 @@
 package com.fdkankan.reg.dto;
 
+import com.alibaba.fastjson2.annotation.JSONField;
 import lombok.Data;
 
 /**
@@ -10,8 +11,11 @@ public class CamRegDto {
      /**
      * {"SN": "SN000001", "TOSN": "", "OPTION": "ADD"}
      **/
+    @JSONField(name = "SN")
     private String sn;
+    @JSONField(name = "TOSN")
     private String toSn;
+    @JSONField(name = "CAMERATYPE")
     private Integer cameraType; // 1,看看,9看见,10深时,11深光
 
 }

+ 6 - 0
4dkankan-utils-reg/src/main/java/com/fdkankan/reg/dto/CamRegSDto.java

@@ -1,6 +1,8 @@
 package com.fdkankan.reg.dto;
 
+import com.alibaba.fastjson2.annotation.JSONField;
 import com.fdkankan.reg.EnvType;
+import lombok.Builder;
 import lombok.Data;
 
 import java.util.List;
@@ -10,9 +12,13 @@ import java.util.List;
  */
 @Data
 public class CamRegSDto {
+    @JSONField(name = "MACHINECODE")
     private String machineCode;
+    @JSONField(name = "TIMESTAMP")
     private Long timestamp=System.currentTimeMillis();
+    @JSONField(name = "ENV")
     private String env;
+    @JSONField(name = "CAMREGS")
     List<CamRegDto> camRegs;
 
 }

+ 283 - 0
4dkankan-utils-sms/src/main/java/com/fdkankan/sms/SmsServiceHuawei.java

@@ -0,0 +1,283 @@
+package com.fdkankan.sms;
+
+import cn.hutool.log.Log;
+import lombok.extern.slf4j.Slf4j;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.stereotype.Component;
+
+import java.io.BufferedReader;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.OutputStreamWriter;
+import java.io.UnsupportedEncodingException;
+import java.io.Writer;
+import java.net.URL;
+import java.net.URLEncoder;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+import java.security.cert.CertificateException;
+import java.security.cert.X509Certificate;
+import java.text.SimpleDateFormat;
+//如果JDK版本是1.8,可使用原生Base64类
+import java.util.Base64;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.UUID;
+
+import javax.net.ssl.HostnameVerifier;
+import javax.net.ssl.HttpsURLConnection;
+import javax.net.ssl.SSLContext;
+import javax.net.ssl.SSLSession;
+import javax.net.ssl.TrustManager;
+import javax.net.ssl.X509TrustManager;
+
+//如果JDK版本低于1.8,请使用三方库提供Base64类
+//import org.apache.commons.codec.binary.Base64;
+
+@Component
+public class SmsServiceHuawei {
+
+    private static Logger log = LoggerFactory.getLogger("programLog");
+
+    //无需修改,用于格式化鉴权头域,给"X-WSSE"参数赋值
+    private static final String WSSE_HEADER_FORMAT = "UsernameToken Username=\"%s\",PasswordDigest=\"%s\",Nonce=\"%s\",Created=\"%s\"";
+    //无需修改,用于格式化鉴权头域,给"Authorization"参数赋值
+    private static final String AUTH_HEADER_VALUE = "WSSE realm=\"SDP\",profile=\"UsernameToken\",type=\"Appkey\"";
+
+    @Value("${sms.huawei.sign:1}")
+    private String signature;
+    @Value("${sms.huawei.accessKey:1}")
+    private String appKey;
+    @Value("${sms.huawei.accessKeySecret:1}")
+    private String appSecret;
+    @Value("${sms.huawei.sender:1}")
+    private String sender;
+    @Value("${sms.huawei.url:https://smsapi.cn-north-4.myhuaweicloud.com:443}")
+    private String url;
+    @Value("${sms.huawei.templateId:1}")
+    private String templateId;
+
+    /**
+     对接文档:https://support.huaweicloud.com/msgsms/index.html
+     API 接入地址
+     https://smsapi.cn-north-4.myhuaweicloud.com:443
+     Application Key
+     IDL67FER02ssKO80UWt3XUeH518t
+     Application Secret
+     ozdfzuJZ8CxAcZBtutaeH6sMn59U
+     签名:四川党的建设
+     签名ID:9d2430fa-ecaa-49fc-971d-19f3e9cd5917
+     通道号:8823011831540
+     模板id:d4e922c65bfd4504a8d32c08129b76ba
+
+     模板:欢迎您,您的验证码是${1}(该验证码30分钟内有效,请勿泄露给他人,如非本人操作,请忽视此信息)
+     */
+
+
+    public  void sendSms(String phoneNum, String templateParas) throws Exception {
+        templateParas = "["+templateParas+"]";
+
+        String receiver = "+86"+phoneNum; //短信接收人号码
+        String statusCallBack = "";
+        /**
+         * 选填,使用无变量模板时请赋空值 String templateParas = "";
+         * 单变量模板示例:模板内容为"您的验证码是${1}"时,templateParas可填写为"[\"369751\"]"
+         * 双变量模板示例:模板内容为"您有${1}件快递请到${2}领取"时,templateParas可填写为"[\"3\",\"人民公园正门\"]"
+         * 模板中的每个变量都必须赋值,且取值不能为空
+         * 查看更多模板规范和变量规范:产品介绍>短信模板须知和短信变量须知
+         */
+        //String templateParas = "[\"369751\"]"; //模板变量,此处以单变量验证码短信为例,请客户自行生成6位验证码,并定义为字符串类型,以杜绝首位0丢失的问题(例如:002569变成了2569)。
+        //templateParas =templateParas.replace("{","[").replace("}","]").replace( "\"code\":","");
+        //请求Body,不携带签名名称时,signature请填null
+        String body = buildRequestBody(sender, receiver, templateId, templateParas, statusCallBack, signature);
+        log.info("sendSms:body{}",body);
+        if (null == body || body.isEmpty()) {
+            log.info("body is null.");
+            return;
+        }
+
+        //请求Headers中的X-WSSE参数值
+        String wsseHeader = buildWsseHeader(appKey, appSecret);
+        log.info("sendSms:wsseHeader{}",wsseHeader);
+        if (null == wsseHeader || wsseHeader.isEmpty()) {
+            log.info("wsse header is null.");
+            return;
+        }
+
+        Writer out = null;
+        BufferedReader in = null;
+        StringBuffer result = new StringBuffer();
+        HttpsURLConnection connection = null;
+        InputStream is = null;
+
+
+        HostnameVerifier hv = new HostnameVerifier() {
+
+            @Override
+            public boolean verify(String hostname, SSLSession session) {
+                return true;
+            }
+        };
+        trustAllHttpsCertificates();
+
+        try {
+            log.info("sendSms:url{}",url);
+
+            URL realUrl = new URL(url);
+            connection = (HttpsURLConnection) realUrl.openConnection();
+
+            connection.setHostnameVerifier(hv);
+            connection.setDoOutput(true);
+            connection.setDoInput(true);
+            connection.setUseCaches(true);
+            //请求方法
+            connection.setRequestMethod("POST");
+            //请求Headers参数
+            connection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
+            connection.setRequestProperty("Authorization", AUTH_HEADER_VALUE);
+            connection.setRequestProperty("X-WSSE", wsseHeader);
+
+            connection.connect();
+            out = new OutputStreamWriter(connection.getOutputStream());
+            out.write(body); //发送请求Body参数
+            out.flush();
+            out.close();
+
+            int status = connection.getResponseCode();
+            if (200 == status) { //200
+                is = connection.getInputStream();
+            } else { //400/401
+                is = connection.getErrorStream();
+            }
+            in = new BufferedReader(new InputStreamReader(is, "UTF-8"));
+            String line = "";
+            while ((line = in.readLine()) != null) {
+                result.append(line);
+            }
+            log.info(result.toString()); //打印响应消息实体
+        } catch (Exception e) {
+            e.printStackTrace();
+        } finally {
+            try {
+                if (null != out) {
+                    out.close();
+                }
+                if (null != is) {
+                    is.close();
+                }
+                if (null != in) {
+                    in.close();
+                }
+            } catch (Exception e) {
+                e.printStackTrace();
+            }
+        }
+    }
+
+    /**
+     * 构造请求Body体
+     * @param sender
+     * @param receiver
+     * @param templateId
+     * @param templateParas
+     * @param statusCallBack
+     * @param signature | 签名名称,使用国内短信通用模板时填写
+     * @return
+     */
+    static String buildRequestBody(String sender, String receiver, String templateId, String templateParas,
+                                   String statusCallBack, String signature) {
+        if (null == sender || null == receiver || null == templateId || sender.isEmpty() || receiver.isEmpty()
+                || templateId.isEmpty()) {
+            log.info("buildRequestBody(): sender, receiver or templateId is null.");
+            return null;
+        }
+        Map<String, String> map = new HashMap<String, String>();
+
+        map.put("from", sender);
+        map.put("to", receiver);
+        map.put("templateId", templateId);
+        if (null != templateParas && !templateParas.isEmpty()) {
+            map.put("templateParas", templateParas);
+        }
+        if (null != statusCallBack && !statusCallBack.isEmpty()) {
+            map.put("statusCallback", statusCallBack);
+        }
+        if (null != signature && !signature.isEmpty()) {
+            map.put("signature", signature);
+        }
+
+        StringBuilder sb = new StringBuilder();
+        String temp = "";
+
+        for (String s : map.keySet()) {
+            try {
+                temp = URLEncoder.encode(map.get(s), "UTF-8");
+            } catch (UnsupportedEncodingException e) {
+                e.printStackTrace();
+            }
+            sb.append(s).append("=").append(temp).append("&");
+        }
+
+        return sb.deleteCharAt(sb.length()-1).toString();
+    }
+
+    /**
+     * 构造X-WSSE参数值
+     * @param appKey
+     * @param appSecret
+     * @return
+     */
+    static String buildWsseHeader(String appKey, String appSecret) {
+        if (null == appKey || null == appSecret || appKey.isEmpty() || appSecret.isEmpty()) {
+            log.info("buildWsseHeader(): appKey or appSecret is null.");
+            return null;
+        }
+        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'");
+        String time = sdf.format(new Date()); //Created
+        String nonce = UUID.randomUUID().toString().replace("-", ""); //Nonce
+
+        MessageDigest md;
+        byte[] passwordDigest = null;
+
+        try {
+            md = MessageDigest.getInstance("SHA-256");
+            md.update((nonce + time + appSecret).getBytes());
+            passwordDigest = md.digest();
+        } catch (NoSuchAlgorithmException e) {
+            e.printStackTrace();
+        }
+
+        //如果JDK版本是1.8,请加载原生Base64类,并使用如下代码
+        String passwordDigestBase64Str = Base64.getEncoder().encodeToString(passwordDigest); //PasswordDigest
+        //如果JDK版本低于1.8,请加载三方库提供Base64类,并使用如下代码
+        //String passwordDigestBase64Str = Base64.encodeBase64String(passwordDigest); //PasswordDigest
+        //若passwordDigestBase64Str中包含换行符,请执行如下代码进行修正
+        //passwordDigestBase64Str = passwordDigestBase64Str.replaceAll("[\\s*\t\n\r]", "");
+        return String.format(WSSE_HEADER_FORMAT, appKey, passwordDigestBase64Str, nonce, time);
+    }
+
+    /*** @throws Exception
+     */
+    static void trustAllHttpsCertificates() throws Exception {
+        TrustManager[] trustAllCerts = new TrustManager[] {
+                new X509TrustManager() {
+                    public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {
+                        return;
+                    }
+                    public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {
+                        return;
+                    }
+                    public X509Certificate[] getAcceptedIssuers() {
+                        return null;
+                    }
+                }
+        };
+        SSLContext sc = SSLContext.getInstance("SSL");
+        sc.init(null, trustAllCerts, null);
+        HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());
+    }
+}
+

+ 2 - 18
pom.xml

@@ -41,22 +41,6 @@
     <version>JG-3.0.0-SNAPSHOT</version>
     <packaging>pom</packaging>
 
-
-    <repositories>
-        <repository>
-            <id>releases</id>
-            <url>http://192.168.0.115:8081/nexus-2.14.2-01/content/repositories/releases/</url>
-        </repository>
-        <repository>
-            <id>nexus-aliyun</id>
-            <url>http://maven.aliyun.com/nexus/content/groups/public</url>
-        </repository>
-        <repository>
-            <id>snapshots</id>
-            <url>http://192.168.0.115:8081/nexus-2.14.2-01/content/repositories/snapshots/</url>
-        </repository>
-    </repositories>
-
     <properties>
         <java.version>1.8</java.version>
         <fastjson-version>1.2.83</fastjson-version>
@@ -221,12 +205,12 @@
     <distributionManagement>
         <repository>
             <!-- 这里的ID要和setting的id一致 -->
-            <id>releases</id>
+            <id>fdkk-releases</id>
             <url>http://192.168.0.115:8081/nexus-2.14.2-01/content/repositories/releases/</url>
         </repository>
         <!--这是打成快照版本的配置 -->
         <snapshotRepository>
-            <id>snapshots</id>
+            <id>fdkk-snapshots</id>
             <url>http://192.168.0.115:8081/nexus-2.14.2-01/content/repositories/snapshots/</url>
         </snapshotRepository>
     </distributionManagement>