dengsixing 1 éve
commit
14410db2c0
37 módosított fájl, 15825 hozzáadás és 0 törlés
  1. 30 0
      .gitignore
  2. 78 0
      dependency-reduced-pom.xml
  3. 203 0
      pom.xml
  4. 19 0
      src/main/java/com/fdkankan/modeldemo/Application.java
  5. 62 0
      src/main/java/com/fdkankan/modeldemo/bean/ResultData.java
  6. 109 0
      src/main/java/com/fdkankan/modeldemo/bean/SceneEditControlsBean.java
  7. 232 0
      src/main/java/com/fdkankan/modeldemo/bean/SceneJsonBean.java
  8. 12 0
      src/main/java/com/fdkankan/modeldemo/bean/TietaResBean.java
  9. 15 0
      src/main/java/com/fdkankan/modeldemo/constant/Constant.java
  10. 33 0
      src/main/java/com/fdkankan/modeldemo/constant/ServerCode.java
  11. 20 0
      src/main/java/com/fdkankan/modeldemo/dto/SendConvertDTO.java
  12. 66 0
      src/main/java/com/fdkankan/modeldemo/entity/Scene.java
  13. 50 0
      src/main/java/com/fdkankan/modeldemo/entity/SceneFileMapping.java
  14. 186 0
      src/main/java/com/fdkankan/modeldemo/generator/MappingGeneratorOracle.java
  15. 16 0
      src/main/java/com/fdkankan/modeldemo/mapper/SceneFileMappingMapper.java
  16. 16 0
      src/main/java/com/fdkankan/modeldemo/mapper/SceneMapper.java
  17. 102 0
      src/main/java/com/fdkankan/modeldemo/mq/ConvertListener.java
  18. 7340 0
      src/main/java/com/fdkankan/modeldemo/proto/BigSceneProto.java
  19. 4345 0
      src/main/java/com/fdkankan/modeldemo/proto/Visionmodeldata.java
  20. 1603 0
      src/main/java/com/fdkankan/modeldemo/proto/format/JsonFormat.java
  21. 10 0
      src/main/java/com/fdkankan/modeldemo/service/IConvertService.java
  22. 18 0
      src/main/java/com/fdkankan/modeldemo/service/SceneFileMappingService.java
  23. 18 0
      src/main/java/com/fdkankan/modeldemo/service/SceneService.java
  24. 20 0
      src/main/java/com/fdkankan/modeldemo/service/impl/ConvertServiceImpl.java
  25. 25 0
      src/main/java/com/fdkankan/modeldemo/service/impl/SceneFileMappingServiceImpl.java
  26. 25 0
      src/main/java/com/fdkankan/modeldemo/service/impl/SceneServiceImpl.java
  27. 102 0
      src/main/java/com/fdkankan/modeldemo/utils/CmdUtils.java
  28. 235 0
      src/main/java/com/fdkankan/modeldemo/utils/ConvertUtil.java
  29. 171 0
      src/main/java/com/fdkankan/modeldemo/utils/CreateObjUtil.java
  30. 158 0
      src/main/java/com/fdkankan/modeldemo/utils/CutImgUtil.java
  31. 110 0
      src/main/java/com/fdkankan/modeldemo/utils/FdfsUtil.java
  32. 78 0
      src/main/java/com/fdkankan/modeldemo/utils/StreamGobblerLine.java
  33. 38 0
      src/main/resources/application-test.yml
  34. 3 0
      src/main/resources/application.yml
  35. 234 0
      src/main/resources/logback-spring.xml
  36. 19 0
      src/main/resources/mapper/SceneFileMappingMapper.xml
  37. 24 0
      src/main/resources/mapper/SceneMapper.xml

+ 30 - 0
.gitignore

@@ -0,0 +1,30 @@
+ HELP.md
+/target/
+!.mvn/wrapper/maven-wrapper.jar
+
+### STS ###
+.apt_generated
+.classpath
+.factorypath
+.project
+.settings
+.springBeans
+.sts4-cache
+
+### IntelliJ IDEA ###
+.idea
+*.iws
+*.iml
+*.ipr
+*.log
+
+### NetBeans ###
+/nbproject/private/
+/nbbuild/
+/dist/
+/nbdist/
+/.nb-gradle/
+/build/
+
+### VS Code ###
+.vscode/

+ 78 - 0
dependency-reduced-pom.xml

@@ -0,0 +1,78 @@
+<?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/maven-v4_0_0.xsd">
+  <modelVersion>4.0.0</modelVersion>
+  <groupId>com.fdkankan.model</groupId>
+  <artifactId>4dkankan-utils-model-demo</artifactId>
+  <name>4dkankan-utils-model-demo</name>
+  <version>1.0-SNAPSHOT</version>
+  <url>http://www.example.com</url>
+  <build>
+    <finalName>${artifactId}</finalName>
+    <plugins>
+      <plugin>
+        <artifactId>maven-shade-plugin</artifactId>
+        <version>2.4.1</version>
+        <executions>
+          <execution>
+            <phase>package</phase>
+            <goals>
+              <goal>shade</goal>
+            </goals>
+            <configuration>
+              <transformers>
+                <transformer>
+                  <mainClass>com.fdkankan.modeldemo.utils.CutImgUtil</mainClass>
+                </transformer>
+              </transformers>
+            </configuration>
+          </execution>
+        </executions>
+      </plugin>
+      <plugin>
+        <artifactId>maven-compiler-plugin</artifactId>
+        <configuration>
+          <source>8</source>
+          <target>8</target>
+        </configuration>
+      </plugin>
+    </plugins>
+  </build>
+  <repositories>
+    <repository>
+      <id>releases</id>
+      <url>http://192.168.0.115:8081/nexus-2.14.2-01/content/repositories/releases/</url>
+    </repository>
+    <repository>
+      <id>snapshots</id>
+      <url>http://192.168.0.115:8081/nexus-2.14.2-01/content/repositories/snapshots/</url>
+    </repository>
+    <repository>
+      <id>nexus-aliyun</id>
+      <url>http://maven.aliyun.com/nexus/content/groups/public</url>
+    </repository>
+  </repositories>
+  <dependencies>
+    <dependency>
+      <groupId>org.projectlombok</groupId>
+      <artifactId>lombok</artifactId>
+      <version>1.18.20</version>
+      <scope>provided</scope>
+    </dependency>
+  </dependencies>
+  <distributionManagement>
+    <repository>
+      <id>releases</id>
+      <url>http://192.168.0.115:8081/nexus-2.14.2-01/content/repositories/releases/</url>
+    </repository>
+    <snapshotRepository>
+      <id>snapshots</id>
+      <url>http://192.168.0.115:8081/nexus-2.14.2-01/content/repositories/snapshots/</url>
+    </snapshotRepository>
+  </distributionManagement>
+  <properties>
+    <maven.compiler.source>1.7</maven.compiler.source>
+    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+    <maven.compiler.target>1.7</maven.compiler.target>
+  </properties>
+</project>
+

+ 203 - 0
pom.xml

@@ -0,0 +1,203 @@
+<?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">
+  <modelVersion>4.0.0</modelVersion>
+
+  <parent>
+    <groupId>org.springframework.boot</groupId>
+    <artifactId>spring-boot-starter-parent</artifactId>
+    <version>2.3.12.RELEASE</version>
+    <relativePath/>
+  </parent>
+
+  <groupId>com.fdkankan.model</groupId>
+  <artifactId>4dkankan-utils-model-demo</artifactId>
+  <version>1.0-SNAPSHOT</version>
+
+  <name>4dkankan-utils-model-demo</name>
+  <!-- FIXME change it to the project's website -->
+  <url>http://www.example.com</url>
+
+  <repositories>
+    <repository>
+      <id>releases</id>
+      <url>http://192.168.0.115:8081/nexus-2.14.2-01/content/repositories/releases/</url>
+    </repository>
+    <repository>
+      <id>snapshots</id>
+      <url>http://192.168.0.115:8081/nexus-2.14.2-01/content/repositories/snapshots/</url>
+    </repository>
+    <repository>
+      <id>nexus-aliyun</id>
+      <url>http://maven.aliyun.com/nexus/content/groups/public</url>
+    </repository>
+  </repositories>
+
+  <properties>
+    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+    <maven.compiler.source>1.8</maven.compiler.source>
+    <maven.compiler.target>1.8</maven.compiler.target>
+  </properties>
+
+  <dependencies>
+
+    <dependency>
+      <groupId>org.slf4j</groupId>
+      <artifactId>slf4j-api</artifactId>
+      <version>1.7.30</version>
+    </dependency>
+
+    <dependency>
+      <groupId>org.projectlombok</groupId>
+      <artifactId>lombok</artifactId>
+      <version>1.18.20</version>
+      <scope>provided</scope>
+    </dependency>
+
+    <dependency>
+      <groupId>com.google.protobuf</groupId>
+      <artifactId>protobuf-java</artifactId>
+      <version>3.2.0</version>
+    </dependency>
+
+    <dependency>
+      <groupId>com.alibaba</groupId>
+      <artifactId>fastjson</artifactId>
+      <version>1.2.83</version>
+    </dependency>
+
+    <dependency>
+      <groupId>cn.hutool</groupId>
+      <artifactId>hutool-all</artifactId>
+      <version>5.7.17</version>
+    </dependency>
+
+    <dependency>
+      <groupId>com.fdkankan</groupId>
+      <artifactId>4dkankan-utils-rabbitmq</artifactId>
+      <version>3.0.0-SNAPSHOT</version>
+    </dependency>
+
+    <dependency>
+      <groupId>org.springframework.boot</groupId>
+      <artifactId>spring-boot-starter-web</artifactId>
+    </dependency>
+
+    <dependency>
+      <groupId>org.springframework.boot</groupId>
+      <artifactId>spring-boot-starter-validation</artifactId>
+    </dependency>
+
+    <dependency>
+      <groupId>com.yomahub</groupId>
+      <artifactId>tlog-web-spring-boot-starter</artifactId>
+      <version>1.3.6</version>
+    </dependency>
+
+    <dependency>
+      <groupId>com.yomahub</groupId>
+      <artifactId>tlog-feign-spring-boot-starter</artifactId>
+      <version>1.3.6</version>
+    </dependency>
+
+    <dependency>
+      <groupId>com.oracle</groupId>
+      <artifactId>ojdbc6</artifactId>
+      <version>11.2.0.3</version>
+    </dependency>
+    <!--mybatis-plus整合依赖-->
+    <dependency>
+      <groupId>com.baomidou</groupId>
+      <artifactId>mybatis-plus-boot-starter</artifactId>
+      <version>3.0.5</version>
+    </dependency>
+
+    <!-- mybatis-plus逆向工程依赖 -->
+    <dependency>
+      <groupId>com.baomidou</groupId>
+      <artifactId>mybatis-plus-generator</artifactId>
+      <version>3.2.0</version>
+    </dependency>
+
+    <!-- freemarker 说明:mybatis-plus逆向工程需要freemarker模板引擎 -->
+    <dependency>
+      <groupId>org.freemarker</groupId>
+      <artifactId>freemarker</artifactId>
+    </dependency>
+
+  </dependencies>
+
+  <build>
+<!--    <finalName>${artifactId}</finalName>-->
+<!--    <plugins>-->
+<!--      <plugin>-->
+<!--        <groupId>org.apache.maven.plugins</groupId>-->
+<!--        <artifactId>maven-shade-plugin</artifactId>-->
+<!--        <version>2.4.1</version>-->
+<!--        <executions>-->
+<!--          <execution>-->
+<!--            <phase>package</phase>-->
+<!--            <goals>-->
+<!--              <goal>shade</goal>-->
+<!--            </goals>-->
+<!--            <configuration>-->
+<!--              <transformers>-->
+<!--                <transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">-->
+<!--                  <mainClass>com.fdkankan.modeldemo.utils.CutImgUtil</mainClass>-->
+<!--                </transformer>-->
+<!--              </transformers>-->
+<!--            </configuration>-->
+<!--          </execution>-->
+<!--        </executions>-->
+<!--      </plugin>-->
+<!--      <plugin>-->
+<!--        <groupId>org.apache.maven.plugins</groupId>-->
+<!--        <artifactId>maven-compiler-plugin</artifactId>-->
+<!--        <configuration>-->
+<!--          <source>8</source>-->
+<!--          <target>8</target>-->
+<!--        </configuration>-->
+<!--      </plugin>-->
+<!--    </plugins>-->
+
+    <finalName>4dkankan-center-convert</finalName>
+
+    <plugins>
+      <plugin>
+        <groupId>org.springframework.boot</groupId>
+        <artifactId>spring-boot-maven-plugin</artifactId>
+      </plugin>
+
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-surefire-plugin</artifactId>
+        <configuration>
+          <testFailureIgnore>true</testFailureIgnore>
+        </configuration>
+      </plugin>
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-compiler-plugin</artifactId>
+        <configuration>
+          <source>8</source>
+          <target>8</target>
+        </configuration>
+      </plugin>
+    </plugins>
+
+
+  </build>
+
+  <distributionManagement>
+    <repository>
+      <id>releases</id>
+      <url>http://192.168.0.115:8081/nexus-2.14.2-01/content/repositories/releases/</url>
+    </repository>
+
+    <snapshotRepository>
+      <id>snapshots</id>
+      <url>http://192.168.0.115:8081/nexus-2.14.2-01/content/repositories/snapshots/</url>
+    </snapshotRepository>
+  </distributionManagement>
+</project>

+ 19 - 0
src/main/java/com/fdkankan/modeldemo/Application.java

@@ -0,0 +1,19 @@
+package com.fdkankan.modeldemo;
+
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.context.annotation.ComponentScan;
+import org.springframework.scheduling.annotation.EnableAsync;
+import org.springframework.scheduling.annotation.EnableScheduling;
+
+@SpringBootApplication
+@EnableScheduling
+@ComponentScan(basePackages = {"com.fdkankan.*"})
+@EnableAsync
+public class Application {
+    public static void main(String[] args) {
+        SpringApplication.run(Application.class, args);
+    }
+}
+
+

+ 62 - 0
src/main/java/com/fdkankan/modeldemo/bean/ResultData.java

@@ -0,0 +1,62 @@
+package com.fdkankan.modeldemo.bean;
+
+import com.fdkankan.modeldemo.constant.ServerCode;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import java.io.Serializable;
+import java.util.Calendar;
+
+@Data
+@NoArgsConstructor
+@AllArgsConstructor
+public class ResultData<T> implements Serializable {
+    /**
+     * 状态码
+     */
+    private int code;
+    /**
+     * 响应信息
+     */
+    private String message;
+    /**
+     * 后端返回结果
+     */
+    private T data;
+    /**
+     * 请求是否成功
+     */
+    private Boolean success;
+    /**
+     * 响应时间戳
+     */
+    private long timestamp = Calendar.getInstance().getTimeInMillis();
+
+    public static ResultData ok() {
+        return ok(null);
+    }
+    public static ResultData ok(Object data) {
+        return ok("成功", data);
+    }
+    public static ResultData ok(String msg, Object data) {
+        return base(ServerCode.SUCCESS.code(), msg, data,true);
+    }
+
+    public static ResultData error(int code, String msg) {
+        return error(code, msg, null); }
+    public static ResultData error(int code, String msg, Object data) {
+        return base(code, msg, data,false);
+    }
+
+
+    private static ResultData  base(int code, String msg, Object data,Boolean success) {
+        ResultData rd = new ResultData();
+        rd.setCode(code);
+        rd.setMessage(msg);
+        rd.setData(data);
+        rd.setSuccess(success);
+        return rd;
+    }
+
+}

+ 109 - 0
src/main/java/com/fdkankan/modeldemo/bean/SceneEditControlsBean.java

@@ -0,0 +1,109 @@
+package com.fdkankan.modeldemo.bean;
+
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import java.io.Serializable;
+
+/**
+ * <p>
+ * TODO
+ * </p>
+ *
+ * @author dengsixing
+ * @since 2022/1/18
+ **/
+@Data
+@Builder
+@NoArgsConstructor
+@AllArgsConstructor
+public class SceneEditControlsBean implements Serializable {
+
+    /**
+     * 是否展示小地图(0-不展示,1-展示)
+     */
+    private Integer showMap;
+
+    /**
+     * 是否需要密码(0-不需要,1-需要)
+     */
+    private Integer showLock;
+
+    /**
+     * 是否展示标题(0-不需要,1-需要)
+     */
+    private Integer showTitle;
+
+    /**
+     * 是否展示漫游按钮(0-不需要,1-需要)
+     */
+    private Integer showPanorama;
+
+    /**
+     * 是否展示3D按钮(0-不需要,1-需要)
+     */
+    private Integer showDollhouse;
+
+    /**
+     * 是否展示2D按钮(0-不需要,1-需要)
+     */
+    private Integer showFloorplan;
+
+    /**
+     * 是否展示VR(0-不需要,1-需要)
+     */
+    private Integer showVR;
+
+    /**
+     * 是否展示自动导览(0-不需要,1-需要)
+     */
+    private Integer showTour;
+
+    /**
+     * 是否展示测量线(0-不需要,1-需要)
+     */
+    private Integer showRule;
+
+    /**
+     * 是否展示标尺(0-不需要,1-需要)
+     */
+    private Integer showScale;
+
+    /**
+     * 是否展示分享场景(0-不需要,1-需要)
+     */
+    private Integer showShare;
+
+    /**
+     * 是否展示分享热点(0-不需要,1-需要)
+     */
+    private Integer showTagshare;
+
+    /**
+     * 是否展示合照开关(0-不需要,1-需要)
+     */
+    private Integer showCapture;
+
+    /**
+     * 多媒体标签标题
+     */
+    private Integer showTagTitle;
+
+    /**
+     * 指示牌标签标题
+     */
+    private Integer showBillboardTitle;
+
+    /**
+     * 视频监控标签标题
+     */
+    private Integer showCameraTitle;
+
+    /**
+     * 场景关联标签标题
+     */
+    private Integer showLinkTitle;
+
+}

+ 232 - 0
src/main/java/com/fdkankan/modeldemo/bean/SceneJsonBean.java

@@ -0,0 +1,232 @@
+package com.fdkankan.modeldemo.bean;
+
+import com.alibaba.fastjson.JSONArray;
+import com.alibaba.fastjson.JSONObject;
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import java.util.Date;
+import java.util.List;
+
+/**
+ * <p>
+ * scene.json实体类
+ * </p>
+ *
+ * @author dengsixing
+ * @since 2022/1/19
+ **/
+@Data
+@Builder
+@NoArgsConstructor
+@AllArgsConstructor
+public class SceneJsonBean {
+
+    /**
+     * 场景码
+     */
+    private String num;
+
+    /**
+     * 地面logo名称
+     */
+    private String floorLogo;
+
+    /**
+     * 地面logo大小
+     */
+    private Integer floorLogoSize;
+
+    /**
+     * 地面logo文件名称
+     */
+    private String floorLogoFile;
+
+    /**
+     * 背景音乐名称
+     */
+    private String music;
+
+    /**
+     * 背景音乐文件名称
+     */
+    private String musicFile;
+
+    /**
+     * 浏览密码
+     */
+    private String scenePassword;
+
+    /**
+     * 场景标题
+     */
+    private String title;
+
+    /**
+     * 场景描述
+     */
+    private String description;
+
+    private SceneEditControlsBean controls;
+
+    /**
+     * 创建时间
+     */
+    private Date createTime;
+
+    /**
+     * 版本
+     */
+    private int version;
+
+    /**
+     * 图片版本
+     */
+    private int imgVersion;
+
+    /**
+     * 场景关联版本
+     */
+    private int linkVersion;
+
+    /**
+     * 是否上传了户型图(0-否,1-是)
+     */
+    private int floorPlanUser;
+
+    /**
+     * 初始点信息
+     */
+    private String entry;
+
+    /**
+     * 全景图加载方式,tiles/1k:1k瓦片图,tiles/2:2k瓦片图,tiles/4k:4k瓦片图,pan:全景图 ,local:本地切片,cube:立体图
+     */
+    private String sceneResolution;
+
+    /**
+     * 场景来源,lite:双目lite相机,pro:八目相机,minion:双面转台相机,laser:激光相机,virtual:虚拟场景,sketch:图片建模场景
+     */
+    private String sceneFrom;
+
+    /**
+     * 切图方式(tiles:瓦片图,face:切片图,pan:全景图 ,local:本地切片,cube:立体图)
+     */
+    private String sceneKind;
+
+    /**
+     * 算法模型类型(dam,3dtiles)
+     */
+    private String modelKind;
+
+    /**
+     * 空间视频数据
+     */
+    private String boxVideos;
+
+    /**
+     * 空间贴图数据
+     */
+    private String boxPhotos;
+
+    /**
+     * 空间模型数据
+     */
+    private String boxModels;
+
+    /**
+     *点位视频
+     */
+    private String videos;
+
+    /**
+     * 是否有热点数据
+     */
+    private Integer tags;
+
+    /**
+     * 加载logo名
+     */
+    private String loadingLogo;
+
+    /**
+     * 加载logo文件名
+     */
+    private String loadingLogoFile;
+
+    private Integer payStatus;
+
+    /**
+     * 户型角度
+     */
+    private Integer floorPlanAngle;
+
+    /**
+     * 指南针角度
+     */
+    private Float floorPlanCompass;
+
+    /**
+     * 用户上传自定义平面图
+     */
+    private JSONArray floorPlanUpload;
+
+    /**
+     * 是否保存导览
+     */
+    private Integer tours;
+
+    /**
+     * 是否有场景关联(0-否,1-是)
+     */
+    private Integer links;
+
+    /**
+     * 是否有马赛克
+     */
+    private Integer mosaic;
+
+    /**
+     * 马赛克列表
+     */
+    private List<JSONObject> mosaicList;
+
+    /**
+     * 水印文件名
+     */
+    private String waterMark;
+
+    /**
+     * 是否有滤镜(0-否,1-是)
+     */
+    private Integer filters;
+
+    /**
+     * 是否有监控摄像头数据
+     */
+    private Integer surveillances;
+
+    /**
+     * 分享信息
+     */
+    private JSONObject sns;
+
+    /**
+     * 是否有指示牌(0-否,1-是)
+     */
+    private Integer billboards;
+
+    /**
+     * 是否有模型裁剪(0-否,1-是)
+     */
+    private Integer cutModel;
+
+    /**
+     * 启动页信息
+     */
+    private JSONObject started;
+
+
+}

+ 12 - 0
src/main/java/com/fdkankan/modeldemo/bean/TietaResBean.java

@@ -0,0 +1,12 @@
+package com.fdkankan.modeldemo.bean;
+
+import lombok.Data;
+
+@Data
+public class TietaResBean<T> {
+
+    private String code;
+    private String mes;
+    private T data;
+
+}

+ 15 - 0
src/main/java/com/fdkankan/modeldemo/constant/Constant.java

@@ -0,0 +1,15 @@
+package com.fdkankan.modeldemo.constant;
+
+public class Constant {
+
+    public static final String QUEUE_SCENE_CONVERT = "queue-scene-convert";
+
+    public static final String DATA_VIEW_PATH =  "scene_view_data/%s/data/";
+    /**
+     * 场景图片
+     */
+    public static final String IMG_VIEW_PATH =  "scene_view_data/%s/images/";
+
+
+
+}

+ 33 - 0
src/main/java/com/fdkankan/modeldemo/constant/ServerCode.java

@@ -0,0 +1,33 @@
+package com.fdkankan.modeldemo.constant;
+
+public enum ServerCode {
+
+	SUCCESS(0, "操作成功"),
+	SYSTEM_ERROR(-1, "服务器异常"),
+	PARAM_ERROR(-2, "解析请求参数出错"),
+	PARAM_REQUIRED(-3, "缺少必要参数:%s"),
+	FEIGN_REQUEST_FAILD(-4, "跨服务请求失败"),
+	SERVER_CLOSING(-5, "服务正在关闭!"),
+
+	APP_ID_ILLEGAL(3100, "非法的APP ID");
+
+	private Integer code;
+	private String message;
+
+	private ServerCode(Integer code, String message) {
+		this.code = code;
+		this.message = message;
+	}
+
+	public Integer code() {
+		return code;
+	}
+
+	public String message() {
+		return message;
+	}
+
+	public String formatMessage(Object... args) {
+		return String.format(message, args);
+	}
+}

+ 20 - 0
src/main/java/com/fdkankan/modeldemo/dto/SendConvertDTO.java

@@ -0,0 +1,20 @@
+package com.fdkankan.modeldemo.dto;
+
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+import org.springframework.beans.factory.annotation.Autowired;
+
+import javax.validation.constraints.NotBlank;
+
+@Data
+@Builder
+@NoArgsConstructor
+@AllArgsConstructor
+public class SendConvertDTO {
+    @NotBlank(message = "roomId不能为空")
+    private String roomId;
+    @NotBlank(message = "url不能为空")
+    private String url;
+}

+ 66 - 0
src/main/java/com/fdkankan/modeldemo/entity/Scene.java

@@ -0,0 +1,66 @@
+package com.fdkankan.modeldemo.entity;
+
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import com.baomidou.mybatisplus.extension.activerecord.Model;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.experimental.Accessors;
+
+import java.io.Serializable;
+
+/**
+ * <p>
+ *
+ * </p>
+ *
+ * @author dsx
+ * @since 2024-06-26
+ */
+@Data
+@EqualsAndHashCode(callSuper = false)
+@Accessors(chain = true)
+@TableName("T_SCENE")
+public class Scene extends Model<Scene> {
+
+    private static final long serialVersionUID = 1L;
+
+    @TableId(value = "ID", type = IdType.AUTO)
+    private Long id;
+
+    @TableField("TITLE")
+    private String title;
+
+    @TableField("DESCRIPTION")
+    private String description;
+
+    @TableField("NUM")
+    private String num;
+
+    @TableField("FLOORLOGOSIZE")
+    private Integer floorlogosize;
+
+    @TableField("SCENEKIND")
+    private String scenekind;
+
+    @TableField("SCENERESOLUTION")
+    private String sceneresolution;
+
+    @TableField("SCENEFROM")
+    private String scenefrom;
+
+    @TableField("MODELKIND")
+    private String modelkind;
+
+    @TableField("FLOORPLANANGLE")
+    private Integer floorplanangle;
+
+
+    @Override
+    protected Serializable pkVal() {
+        return this.id;
+    }
+
+}

+ 50 - 0
src/main/java/com/fdkankan/modeldemo/entity/SceneFileMapping.java

@@ -0,0 +1,50 @@
+package com.fdkankan.modeldemo.entity;
+
+import com.baomidou.mybatisplus.annotation.TableName;
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.extension.activerecord.Model;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableField;
+import java.io.Serializable;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.experimental.Accessors;
+
+/**
+ * <p>
+ *
+ * </p>
+ *
+ * @author dsx
+ * @since 2024-06-26
+ */
+@Data
+@EqualsAndHashCode(callSuper = false)
+@Accessors(chain = true)
+@TableName("T_SCENE_FILE_MAPPING")
+public class SceneFileMapping extends Model<SceneFileMapping> {
+
+    private static final long serialVersionUID = 1L;
+
+    @TableId(value = "ID", type = IdType.AUTO)
+    private String id;
+
+    @TableField("NUM")
+    private String num;
+
+    @TableField("FILEID")
+    private String fileid;
+
+    @TableField("KEY")
+    private String key;
+
+    @TableField("URL")
+    private String url;
+
+
+    @Override
+    protected Serializable pkVal() {
+        return this.id;
+    }
+
+}

+ 186 - 0
src/main/java/com/fdkankan/modeldemo/generator/MappingGeneratorOracle.java

@@ -0,0 +1,186 @@
+package com.fdkankan.modeldemo.generator;
+
+import com.baomidou.mybatisplus.annotation.DbType;
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.generator.AutoGenerator;
+import com.baomidou.mybatisplus.generator.config.DataSourceConfig;
+import com.baomidou.mybatisplus.generator.config.GlobalConfig;
+import com.baomidou.mybatisplus.generator.config.PackageConfig;
+import com.baomidou.mybatisplus.generator.config.StrategyConfig;
+import com.baomidou.mybatisplus.generator.config.converts.MySqlTypeConvert;
+import com.baomidou.mybatisplus.generator.config.rules.NamingStrategy;
+import com.baomidou.mybatisplus.generator.engine.FreemarkerTemplateEngine;
+
+/**
+ * 代码生成器
+ *
+ * <p>
+ * 根据数据库中的表生成:数据库表映射对象、Mapper 接口、Mapper XML 文件(含基础的 ResultMap 和字段代码片段)、 Service
+ * 接口、Service 接口实现累、基础的 Controller 类。
+ * </p>
+ * <p>
+ * 如果数据库设计符合规范,并且代码没有特殊要求。设置好表名前缀(无则忽略)、表字段前缀(无则忽略)后, 直接修改输出的路径、JDBC
+ * Url、数据库的账户和密码即可直接生成代码。
+ * </p>
+ * <p>
+ * 生成后将 Mapper 中的 xml 包中的 XML 文件移动到 resource 下即可,XML 存放文件夹名为 Mapper
+ * 接口包名(全包名)的同名文件夹<br/>
+ * 如 Mapper 接口包名为:com.example.mapper,那么在 resource 下新建同名文件夹:com.example.mapper,将
+ * xml 文件移动到该文件夹下即可。
+ * </p>
+ *
+ * @author wayne
+ * @since 2020-01-08 23:00
+ */
+public class MappingGeneratorOracle {
+
+	/**
+	 * 生成代码输出路径,<strong>路径必须是绝对路径,不需要包含包名</strong>
+	 */
+	private static final String OUTPUT_DIR = ".\\src\\main\\java\\com\\fdkankan\\modeldemo\\generator";
+	/**
+	 * 生成代码输出的包名
+	 * <p>
+	 * 总包名,后续生成的 Mapper,Service 等将在该包下生成子包
+	 * </p>
+	 */
+	private static final String PACKAGE = "com.fdkankan.project.tieta";
+	/**
+	 * JDBC URL 说明: url地址前需要加上@,否则会报错
+	 */
+
+	private static final String JDBC_URL = "jdbc:oracle:thin:@//8.135.106.227:1521/helowin";
+	/**
+	 * 数据库账户
+	 */
+	private static final String DB_USERNAME = "FDKK";
+	/**
+	 * 数据库账户密码
+	 */
+	private static final String DB_PASSWORD = "qawsed@123.";
+
+	/**
+	 * 执行即可生成代码 需要添加 freemarker 依赖 <dependency> <groupId>org.freemarker</groupId>
+	 * <artifactId>freemarker</artifactId> <version>2.3.29</version> </dependency>
+	 */
+	// 不要在src/main/java里面使用main方法,否则springboot项目某人为main方法的类就是启动类
+//	public static void main(String[] args) {
+//		autoGenerator().execute();
+//	}
+
+	public static AutoGenerator autoGenerator() {
+		AutoGenerator autoGenerator = new AutoGenerator();
+		autoGenerator.setGlobalConfig(globalConfig());
+		autoGenerator.setDataSource(oracleDataSourceConfig());
+		autoGenerator.setStrategy(strategyConfig());
+		autoGenerator.setPackageInfo(packageConfig());
+		autoGenerator.setTemplateEngine(new FreemarkerTemplateEngine());
+		return autoGenerator;
+	}
+
+	public static void main(String[] args) {
+		autoGenerator().execute();
+	}
+
+	/**
+	 * 全局配置
+	 *
+	 * @return {@link GlobalConfig}
+	 */
+	private static GlobalConfig globalConfig() {
+		GlobalConfig globalConfig = new GlobalConfig();
+		globalConfig.setAuthor("dsx");
+		// 设置代码输出位置,需要绝对路径
+		globalConfig.setOutputDir(OUTPUT_DIR);
+		// 覆盖已有的代码
+		globalConfig.setFileOverride(false);
+		// 基本表的 ResultMap
+		globalConfig.setBaseResultMap(true);
+		// 基本表字段片段
+		globalConfig.setBaseColumnList(true);
+		// 开启基于 Model 操作数据库
+		globalConfig.setActiveRecord(true);
+		// 设置 ID 类型
+		globalConfig.setIdType(IdType.AUTO);
+//		// 生成基本 Swagger2 文档
+//		globalConfig.setSwagger2(true);
+		// 开启二级缓存
+//		globalConfig.setEnableCache(true);
+		// 设置生成的对象名称规则,%s 表示当前的 Entity
+		// 数据库表映射对象名称规则
+		globalConfig.setEntityName("%s");
+		// 也可以使用下面这种就是末尾会以DO结尾
+//		globalConfig.setEntityName("%sDO");
+		// Mapper 接口名称规则
+		globalConfig.setMapperName("%sMapper");
+		// Mapper XML 文件名称规则
+		globalConfig.setXmlName("%sMapper");
+		// Controller 生成规则
+		globalConfig.setControllerName("%sController");
+		// Service 接口生成名称规则
+		globalConfig.setServiceName("%sService");
+		// Service 实现类生成名称规则
+		globalConfig.setServiceImplName("%sServiceImpl");
+		return globalConfig;
+	}
+
+	/**
+	 * 生成策略配置
+	 *
+	 * @return StrategyConfig
+	 */
+	private static StrategyConfig strategyConfig() {
+		StrategyConfig strategyConfig = new StrategyConfig();
+		strategyConfig.setCapitalMode(false);
+		strategyConfig.setEntityLombokModel(true);
+		strategyConfig.setRestControllerStyle(true);
+		strategyConfig.setNaming(NamingStrategy.underline_to_camel);
+		strategyConfig.setColumnNaming(NamingStrategy.underline_to_camel);
+		// TODO 填写表前缀、表字段前缀,生成代码时去除字段前缀
+		strategyConfig.setTablePrefix("t_");
+		strategyConfig.setFieldPrefix("a_", "c_", "e_", "f_", "p_", "r_", "t_", "tf_");
+		strategyConfig.setInclude("t_test");
+		return strategyConfig;
+	}
+
+	/**
+	 * MySQL 数据源配置
+	 *
+	 * @return DataSourceConfig
+	 */
+	private static DataSourceConfig oracleDataSourceConfig() {
+		DataSourceConfig dataSourceConfig = new DataSourceConfig();
+		dataSourceConfig.setDbType(DbType.ORACLE);
+		dataSourceConfig.setTypeConvert(new MySqlTypeConvert());
+		dataSourceConfig.setDriverName("oracle.jdbc.driver.OracleDriver");
+		dataSourceConfig.setUrl(JDBC_URL);
+		dataSourceConfig.setUsername(DB_USERNAME);
+		dataSourceConfig.setPassword(DB_PASSWORD);
+		return dataSourceConfig;
+	}
+
+	/**
+	 * 包相关配置信息
+	 * <p>
+	 * 配置生成代码的包信息,如生成的 Mapper 包,Service 包等
+	 * </p>
+	 */
+	private static PackageConfig packageConfig() {
+		PackageConfig packageConfig = new PackageConfig();
+		// 设置父包
+		packageConfig.setParent(PACKAGE);
+		// TODO 设置生成代码的包
+		// Controller 包
+		packageConfig.setController("controller");
+		// 数据库表映射对象包
+		packageConfig.setEntity("entity");
+		// Mapper 接口包,含 XML 文件
+		packageConfig.setMapper("mapper");
+		// Service 接口包
+		packageConfig.setService("service");
+		// Service 接口实现类包
+		packageConfig.setServiceImpl("service.impl");
+		return packageConfig;
+	}
+}
+

+ 16 - 0
src/main/java/com/fdkankan/modeldemo/mapper/SceneFileMappingMapper.java

@@ -0,0 +1,16 @@
+package com.fdkankan.modeldemo.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.fdkankan.modeldemo.entity.SceneFileMapping;
+
+/**
+ * <p>
+ *  Mapper 接口
+ * </p>
+ *
+ * @author dsx
+ * @since 2024-06-26
+ */
+public interface SceneFileMappingMapper extends BaseMapper<SceneFileMapping> {
+
+}

+ 16 - 0
src/main/java/com/fdkankan/modeldemo/mapper/SceneMapper.java

@@ -0,0 +1,16 @@
+package com.fdkankan.modeldemo.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.fdkankan.modeldemo.entity.Scene;
+
+/**
+ * <p>
+ *  Mapper 接口
+ * </p>
+ *
+ * @author dsx
+ * @since 2024-06-26
+ */
+public interface SceneMapper extends BaseMapper<Scene> {
+
+}

+ 102 - 0
src/main/java/com/fdkankan/modeldemo/mq/ConvertListener.java

@@ -0,0 +1,102 @@
+package com.fdkankan.modeldemo.mq;
+
+import cn.hutool.core.io.FileUtil;
+import cn.hutool.core.util.ZipUtil;
+import cn.hutool.http.HttpUtil;
+import com.alibaba.fastjson.JSON;
+import com.alibaba.fastjson.JSONObject;
+import com.fdkankan.modeldemo.bean.SceneEditControlsBean;
+import com.fdkankan.modeldemo.bean.SceneJsonBean;
+import com.fdkankan.modeldemo.constant.Constant;
+import com.fdkankan.modeldemo.entity.Scene;
+import com.fdkankan.modeldemo.entity.SceneFileMapping;
+import com.fdkankan.modeldemo.service.SceneFileMappingService;
+import com.fdkankan.modeldemo.service.SceneService;
+import com.fdkankan.modeldemo.utils.ConvertUtil;
+import com.fdkankan.modeldemo.utils.FdfsUtil;
+import com.rabbitmq.client.Channel;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.amqp.core.Message;
+import org.springframework.amqp.rabbit.annotation.Queue;
+import org.springframework.amqp.rabbit.annotation.RabbitListener;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+import javax.annotation.Resource;
+import java.nio.charset.StandardCharsets;
+import java.util.Map;
+import java.util.Objects;
+
+/**
+ * <p>
+ * TODO
+ * </p>
+ *
+ * @author dengsixing
+ * @since 2022/4/19
+ **/
+@Slf4j
+@Component
+public class ConvertListener{
+
+    @Autowired
+    private ConvertUtil convertUtil;
+    @Resource
+    private FdfsUtil fdfsUtil;
+    @Autowired
+    private SceneFileMappingService sceneFileMappingService;
+    @Autowired
+    private SceneService sceneService;
+
+    @RabbitListener(
+            queuesToDeclare = @Queue(Constant.QUEUE_SCENE_CONVERT),
+            concurrency = "1"
+    )
+    public void buildObjScenePreHandler(Channel channel, Message message) throws Exception {
+        String roomId = null;
+        try {
+            String msg = new String(message.getBody(), StandardCharsets.UTF_8);
+            log.info("msg:{}", msg);
+            JSONObject jsonObject = JSON.parseObject(msg);
+            //roomId
+            roomId = jsonObject.getString("roomId");
+            String zipUrl = jsonObject.getString("zipUrl");
+            String zipName = FileUtil.getName(zipUrl);
+            String dirName = FileUtil.getPrefix(zipName);
+            log.info("zipUrl:{}", zipUrl);
+            //下载压缩包
+            String baseZipPath = "/mnt/scene/convert/";
+            FileUtil.mkdir(baseZipPath);
+            HttpUtil.downloadFile(zipUrl, baseZipPath);
+//            FileUtil.copy(zipUrl, baseZipPath, true);
+
+            String localZipPath = baseZipPath + zipName;
+            ZipUtil.unzip(localZipPath, baseZipPath);
+
+            String targetPath = "/oss/4dkankan/scene_view_data/" + roomId + "/";
+            String dataSource = baseZipPath + dirName + "/";
+            Map<String, String> uploadFileMap = convertUtil.convert(dataSource, roomId);
+            String finalRoomId = roomId;
+            uploadFileMap.keySet().stream().forEach(key->{
+
+                SceneFileMapping sceneFileMapping = sceneFileMappingService.getByNumAndKey(finalRoomId, key);
+                if(Objects.isNull(sceneFileMapping)){
+                    sceneFileMapping = new SceneFileMapping();
+                }
+                Map<String, String> mapping = fdfsUtil.uploadFile(uploadFileMap.get(key));
+                sceneFileMapping.setNum(finalRoomId);
+                sceneFileMapping.setFileid(mapping.get("file_id"));
+                sceneFileMapping.setUrl(mapping.get("http_url"));
+                sceneFileMapping.setKey(key);
+                sceneFileMappingService.saveOrUpdate(sceneFileMapping);
+            });
+
+        }catch (Exception e){
+            log.error("convert fail, roomId:{}", roomId, e);
+        }
+
+        channel.basicAck(message.getMessageProperties().getDeliveryTag(), false);
+
+
+    }
+}

A különbségek nem kerülnek megjelenítésre, a fájl túl nagy
+ 7340 - 0
src/main/java/com/fdkankan/modeldemo/proto/BigSceneProto.java


A különbségek nem kerülnek megjelenítésre, a fájl túl nagy
+ 4345 - 0
src/main/java/com/fdkankan/modeldemo/proto/Visionmodeldata.java


A különbségek nem kerülnek megjelenítésre, a fájl túl nagy
+ 1603 - 0
src/main/java/com/fdkankan/modeldemo/proto/format/JsonFormat.java


+ 10 - 0
src/main/java/com/fdkankan/modeldemo/service/IConvertService.java

@@ -0,0 +1,10 @@
+package com.fdkankan.modeldemo.service;
+
+import com.fdkankan.modeldemo.dto.SendConvertDTO;
+
+public interface IConvertService {
+
+    void sendConvert(SendConvertDTO dto);
+
+
+}

+ 18 - 0
src/main/java/com/fdkankan/modeldemo/service/SceneFileMappingService.java

@@ -0,0 +1,18 @@
+package com.fdkankan.modeldemo.service;
+
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.fdkankan.modeldemo.entity.SceneFileMapping;
+
+/**
+ * <p>
+ *  服务类
+ * </p>
+ *
+ * @author dsx
+ * @since 2024-06-26
+ */
+public interface SceneFileMappingService extends IService<SceneFileMapping> {
+
+    SceneFileMapping getByNumAndKey(String num, String key);
+
+}

+ 18 - 0
src/main/java/com/fdkankan/modeldemo/service/SceneService.java

@@ -0,0 +1,18 @@
+package com.fdkankan.modeldemo.service;
+
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.fdkankan.modeldemo.entity.Scene;
+
+/**
+ * <p>
+ *  服务类
+ * </p>
+ *
+ * @author dsx
+ * @since 2024-06-26
+ */
+public interface SceneService extends IService<Scene> {
+
+    Scene getByNum(String num);
+
+}

+ 20 - 0
src/main/java/com/fdkankan/modeldemo/service/impl/ConvertServiceImpl.java

@@ -0,0 +1,20 @@
+package com.fdkankan.modeldemo.service.impl;
+
+import com.fdkankan.modeldemo.constant.Constant;
+import com.fdkankan.modeldemo.dto.SendConvertDTO;
+import com.fdkankan.modeldemo.service.IConvertService;
+import com.fdkankan.rabbitmq.util.RabbitMqProducer;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+@Service
+public class ConvertServiceImpl implements IConvertService {
+
+    @Autowired
+    private RabbitMqProducer mqProducer;
+
+    @Override
+    public void sendConvert(SendConvertDTO dto) {
+        mqProducer.sendByWorkQueue(Constant.QUEUE_SCENE_CONVERT, dto);
+    }
+}

+ 25 - 0
src/main/java/com/fdkankan/modeldemo/service/impl/SceneFileMappingServiceImpl.java

@@ -0,0 +1,25 @@
+package com.fdkankan.modeldemo.service.impl;
+
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.fdkankan.modeldemo.entity.SceneFileMapping;
+import com.fdkankan.modeldemo.mapper.SceneFileMappingMapper;
+import com.fdkankan.modeldemo.service.SceneFileMappingService;
+import org.springframework.stereotype.Service;
+
+/**
+ * <p>
+ *  服务实现类
+ * </p>
+ *
+ * @author dsx
+ * @since 2024-06-26
+ */
+@Service
+public class SceneFileMappingServiceImpl extends ServiceImpl<SceneFileMappingMapper, SceneFileMapping> implements SceneFileMappingService {
+
+    @Override
+    public SceneFileMapping getByNumAndKey(String num, String key) {
+        return this.getOne(new LambdaQueryWrapper<SceneFileMapping>().eq(SceneFileMapping::getNum, num).eq(SceneFileMapping::getKey, key));
+    }
+}

+ 25 - 0
src/main/java/com/fdkankan/modeldemo/service/impl/SceneServiceImpl.java

@@ -0,0 +1,25 @@
+package com.fdkankan.modeldemo.service.impl;
+
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.fdkankan.modeldemo.entity.Scene;
+import com.fdkankan.modeldemo.mapper.SceneMapper;
+import com.fdkankan.modeldemo.service.SceneService;
+import org.springframework.stereotype.Service;
+
+/**
+ * <p>
+ *  服务实现类
+ * </p>
+ *
+ * @author dsx
+ * @since 2024-06-26
+ */
+@Service
+public class SceneServiceImpl extends ServiceImpl<SceneMapper, Scene> implements SceneService {
+
+    @Override
+    public Scene getByNum(String num) {
+        return this.getOne(new LambdaQueryWrapper<Scene>().eq(Scene::getNum, num));
+    }
+}

+ 102 - 0
src/main/java/com/fdkankan/modeldemo/utils/CmdUtils.java

@@ -0,0 +1,102 @@
+package com.fdkankan.modeldemo.utils;
+
+import lombok.extern.slf4j.Slf4j;
+
+/**
+ * Created by Xiewj on 2021/1/4 0004 14:53
+ */
+public class CmdUtils {
+
+
+    /**
+     * 调用算法 xx.sh 脚本
+     * @param command
+     */
+//    public static void callshell(String command){
+//        try {
+//            String[] cmd = new String[]{"/bin/sh", "-c", command};
+//            Process process = Runtime.getRuntime().exec(cmd);
+//            StreamGobbler errorGobbler = new StreamGobbler(process.getErrorStream(), "ERROR");
+//            errorGobbler.start();
+//            StreamGobbler outGobbler = new StreamGobbler(process.getInputStream(), "STDOUT");
+//            outGobbler.start();
+//            process.waitFor();
+//        } catch (Exception e) {
+//            e.printStackTrace();
+//        }
+//    }
+
+
+
+    public static void callLineSh(String command) throws Exception {
+        callLineSh(command, null);
+
+    }
+
+    /**
+     * 直接java调用命令
+     * @param command
+     */
+    public static void callLine(String command) throws Exception {
+        callLine(command, null);
+
+    }
+
+    /**
+     * 直接java调用命令
+     * @param command
+     */
+    public static void callLine(String command, Integer lineSize) throws Exception {
+        System.out.println("cmd: " + command);
+        Process process = Runtime.getRuntime().exec(command);
+        System.out.println("开始运行");
+        StreamGobblerLine errorGobbler = new StreamGobblerLine(process.getErrorStream(), "ERROR");
+        errorGobbler.start();
+        // 200行打印一次日志
+        StreamGobblerLine outGobbler = new StreamGobblerLine(process.getInputStream(), "STDOUT", lineSize);
+        outGobbler.start();
+        process.waitFor();
+    }
+
+    /**
+     *
+     * @param command 命令
+     * @param lineSize 日志输出行数 ,可以为null
+     */
+    public static void callLineSh(String command, Integer lineSize) throws Exception {
+        try {
+        System.out.println("cmd: " + command);
+        String[] cmd = new String[]{"/bin/sh", "-c", command};
+        Process process = Runtime.getRuntime().exec(cmd);
+        System.out.println("开始运行");
+        StreamGobblerLine errorGobbler = new StreamGobblerLine(process.getErrorStream(), "ERROR");
+        errorGobbler.start();
+        // 200行打印一次日志
+        StreamGobblerLine outGobbler = new StreamGobblerLine(process.getInputStream(), "STDOUT", lineSize);
+        outGobbler.start();
+        process.waitFor();
+        }catch (Exception e){
+            e.printStackTrace();
+        }
+    }
+
+    /**
+     * 调用sh脚本上传oss
+     */
+//    public static void ossUploadDir(String sceneCode, String uploadDir, String target){
+//
+//        String cmd = CmdConstant.OSSUTIL_UPLOAD_DIR;
+//        cmd = cmd.replaceAll("@sceneCode", sceneCode);
+//        cmd = cmd.replaceAll("@uploadDir", uploadDir);
+//        cmd = cmd.replaceAll("@target", target);
+//
+//        log.info("ossCmd: " + cmd);
+//        long start = System.currentTimeMillis();
+//        CmdUtils.callLineSh(cmd);
+//        long end = System.currentTimeMillis();
+//        log.info("场景码目录:{} 上传完成, 耗时:{} s" , sceneCode, (end-start)/1000 );
+//    }
+
+
+
+}

+ 235 - 0
src/main/java/com/fdkankan/modeldemo/utils/ConvertUtil.java

@@ -0,0 +1,235 @@
+package com.fdkankan.modeldemo.utils;
+
+import cn.hutool.core.io.FileUtil;
+import com.alibaba.fastjson.JSON;
+import com.alibaba.fastjson.JSONArray;
+import com.alibaba.fastjson.JSONObject;
+import com.fdkankan.modeldemo.bean.SceneEditControlsBean;
+import com.fdkankan.modeldemo.bean.SceneJsonBean;
+import com.fdkankan.modeldemo.constant.Constant;
+import com.fdkankan.modeldemo.entity.Scene;
+import com.fdkankan.modeldemo.service.SceneService;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+import java.io.File;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
+
+@Component
+public class ConvertUtil {
+
+    @Autowired
+    private SceneService sceneService;
+
+    public static void main(String[] args) throws Exception {
+
+        String srcPath = args[0];
+        System.out.println(srcPath);
+        String targetPath = args[1];
+        System.out.println(targetPath);
+
+//        convert(srcPath, targetPath);
+//		scanner.close();
+    }
+
+    /**
+     *
+     * @param sourcePath 原始资源目录
+     * @param targetPath 目标资源目录
+     * @return boolean true-转换成功  false-转换失败
+     */
+    public Map<String, String> convert(String sourcePath, String num) throws Exception {
+
+        Map<String, String> map = new HashMap<>();
+        String dataViewPath = String.format(Constant.DATA_VIEW_PATH, num);
+        String imgViewPath = String.format(Constant.IMG_VIEW_PATH, num);
+
+        String obj2TxtPath = null;
+
+        if(!sourcePath.endsWith(File.separator)){
+            sourcePath = sourcePath + File.separator;
+        }
+        obj2TxtPath = sourcePath.substring(0, sourcePath.length() - 1) + "_obj2txt";
+        FileUtil.mkdir(obj2TxtPath);
+        //调用算法生成modeldata.txt
+        String extrasPath = obj2TxtPath + File.separator + "extras";
+        FileUtil.mkdir(extrasPath);
+        FileUtil.copyContent(new File(sourcePath + "data" + File.separator + "mesh"), new File(extrasPath), true);
+
+        //写data.json
+        writeDataJson(obj2TxtPath);
+
+        //调用算法建模
+        build3dModel(obj2TxtPath);
+
+        //校验算法是否正常结束
+        String uploadJsonPath = obj2TxtPath + File.separator + "results" +File.separator+"upload.json";
+        boolean success = checkComputeCompleted(uploadJsonPath, 5, 300);
+        if(!success){
+            throw new RuntimeException("计算失败,obj2TxtPath:" + obj2TxtPath);
+        }
+
+        String uploadData = FileUtil.readUtf8String(uploadJsonPath);
+        JSONObject uploadJson = null;
+        JSONArray array = null;
+        if(uploadData!=null) {
+            uploadJson = JSONObject.parseObject(uploadData);
+            array = uploadJson.getJSONArray("upload");
+        }
+        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(obj2TxtPath + File.separator + "results" + File.separator + fileName).exists()) {
+                throw new Exception(obj2TxtPath + File.separator + "results" + File.separator + fileName + "文件不存在");
+            }
+
+            //tex文件夹
+            if (fileJson.getIntValue("clazz") == 15) {
+//                    FileUtil.copy(obj2TxtPath + File.separator + "results" + File.separator + fileName,
+//                            targetImagePath + File.separator + "tieta_texture/" + fileName.replace("tex/", ""),true);
+                map.put(imgViewPath +  "tieta_texture/" + fileName.replace("tex/", ""), obj2TxtPath + File.separator + "results" + File.separator + fileName);
+
+            }
+        }
+
+        //压缩成dam
+        String damKey = imgViewPath + "tieta.dam";
+        String damPath = obj2TxtPath + File.separator + "results" +File.separator + "tieta.dam";
+        CreateObjUtil.convertTxtToDam( obj2TxtPath + File.separator + "results" +File.separator+"modeldata.txt", damPath);
+        map.put(damKey, damPath);
+
+        //复制文件
+        if(FileUtil.exist(sourcePath + "data/" + "floorplan.json")){
+            String floorplanJson = FileUtil.readUtf8String(sourcePath + "data/" + "floorplan.json");
+            JSONObject jsonObject = JSON.parseObject(floorplanJson);
+            Integer currentId = jsonObject.getInteger("currentId");
+            if(Objects.nonNull(currentId) && currentId == 0){
+                FileUtil.del(sourcePath + "data/" + "floorplan.json");
+            }
+        }
+        List<File> dataFiles = FileUtil.loopFiles(sourcePath + "data/");
+        for (File dataFile : dataFiles) {
+            map.put(dataFile.getAbsolutePath().replace(sourcePath + "data/", dataViewPath) , dataFile.getAbsolutePath());
+        }
+
+        String finalSourcePath = sourcePath;
+        if(FileUtil.exist(finalSourcePath + "images/4k/")){
+            FileUtil.listFileNames(sourcePath + "images/4k/").stream().forEach(v->{
+                map.put(imgViewPath + "pan/high/" + v.replaceAll("-", ""), finalSourcePath + "images/4k/" + v);
+//                    FileUtil.copy(finalSourcePath + "images/4k/" + v, targetImagePath + "/pan/high/" + v.replaceAll("-", ""), true);
+            });
+        }
+
+        if(FileUtil.exist(finalSourcePath + "images/512/")){
+            FileUtil.listFileNames(finalSourcePath + "images/512/").stream().forEach(v->{
+                map.put(imgViewPath + "pan/low/" + v.replaceAll("-", ""), finalSourcePath + "images/512/" + v);
+//                    FileUtil.copy(finalSourcePath + "images/512/" + v, targetImagePath + "/pan/low/" + v.replaceAll("-", ""), true);
+            });
+        }
+
+        if(FileUtil.exist(finalSourcePath + "images/8k/")) {
+            FileUtil.listFileNames(finalSourcePath + "images/8k/").stream().forEach(v -> {
+                map.put(imgViewPath + "pan/8k/" + v.replaceAll("-", ""), finalSourcePath + "images/8k/" + v);
+//                    FileUtil.copy(finalSourcePath + "images/8k/" + v, targetImagePath + "/pan/8k/" + v.replaceAll("-", ""), true);
+            });
+
+        }
+        map.put(imgViewPath + "vision.txt", sourcePath + "images/vision.txt");
+//            FileUtil.copy(sourcePath + "images/vision.txt", targetImagePath + "/vision.txt", true);
+
+        //生成vison.modeldata
+        CreateObjUtil.convertTxtToVisionmodeldata(sourcePath + "images/vision.txt", sourcePath + "images/vision.modeldata");
+        map.put(imgViewPath + "vision.modeldata", sourcePath + "images/vision.modeldata");
+
+        //生成场景标题
+        String title = this.getTitle(num, sourcePath);
+
+        //生成scene.json
+        SceneJsonBean sceneJsonBean = this.genSceneJson(num, title);
+        FileUtil.writeUtf8String(JSON.toJSONString(sceneJsonBean), sourcePath + "data/scene.json");
+        map.put(dataViewPath + "scene.json", sourcePath + "data/scene.json");
+
+        return map;
+    }
+
+    private SceneJsonBean genSceneJson(String roomId, String title){
+
+        Scene scene = sceneService.getByNum(roomId);
+        if(Objects.isNull(scene)){
+            scene = new Scene();
+        }
+        scene.setTitle(title);
+        scene.setNum(roomId);
+        scene.setFloorlogosize(100);
+        scene.setScenekind("pano");
+        scene.setSceneresolution("4k");
+        scene.setScenefrom("realsee");
+        scene.setModelkind("dam");
+        scene.setFloorplanangle(0);
+        sceneService.saveOrUpdate(scene);
+
+        SceneEditControlsBean sceneEditControlsBean = SceneEditControlsBean.builder()
+                .showDollhouse(1).showMap(1).showPanorama(1).showVR(1).showTitle(1).showFloorplan(1).build();
+
+        SceneJsonBean sceneJsonBean = SceneJsonBean.builder()
+                .title(title).description(null)
+                .num(roomId).floorLogoSize(100).sceneKind("pano")
+                .sceneResolution("4k").sceneFrom("realsee")
+                .modelKind("dam").floorPlanAngle(0).controls(sceneEditControlsBean).build();
+
+        return sceneJsonBean;
+
+    }
+
+    private String getTitle(String roomId, String sourcePath){
+        String sceneJsonPath =  sourcePath + "data/scene.json";
+        if(!FileUtil.exist(sceneJsonPath)){
+            return roomId;
+        }
+        String sceneJsonStr = FileUtil.readUtf8String(sceneJsonPath);
+        JSONObject jsonObject = JSON.parseObject(sceneJsonStr);
+        String title = jsonObject.getString("title");
+        return Objects.isNull(title) ? roomId : title;
+    }
+
+    public static void writeDataJson(String path){
+        JSONObject dataJson = new JSONObject();
+        dataJson.put("obj2txt", true);
+        dataJson.put("split_type", "SPLIT_V6");
+        dataJson.put("data_describe", "double spherical");
+        dataJson.put("skybox_type", "SKYBOX_V5");
+        FileUtil.writeUtf8String(dataJson.toString(), path + File.separator + "data.json");
+    }
+
+    public static void build3dModel(String folderName) throws Exception {
+        System.out.println("开始建模");
+        String command = "sudo bash /home/ubuntu/bin/Launcher.sh " + folderName;
+        CmdUtils.callLineSh(command);
+        System.out.println("计算完毕:" + command);
+    }
+
+    public static boolean checkComputeCompleted(String uploadJsonPath, int maxCheckTimes, long waitTime) throws Exception {
+        int checkTimes = 1;
+        boolean exist = false;
+
+        do {
+            if ((new File(uploadJsonPath)).exists()) {
+                exist = true;
+                break;
+            }
+
+            Thread.sleep(waitTime);
+            ++checkTimes;
+        } while(checkTimes <= maxCheckTimes);
+
+        return exist;
+    }
+
+}

+ 171 - 0
src/main/java/com/fdkankan/modeldemo/utils/CreateObjUtil.java

@@ -0,0 +1,171 @@
+package com.fdkankan.modeldemo.utils;
+
+import com.alibaba.fastjson.JSON;
+import com.alibaba.fastjson.JSONArray;
+import com.alibaba.fastjson.JSONObject;
+import com.fdkankan.modeldemo.proto.BigSceneProto;
+import com.fdkankan.modeldemo.proto.Visionmodeldata;
+import com.fdkankan.modeldemo.proto.format.JsonFormat;
+import com.google.protobuf.TextFormat;
+import lombok.extern.slf4j.Slf4j;
+
+import java.io.*;
+import java.util.HashMap;
+import java.util.Map;
+
+@Slf4j
+public class CreateObjUtil {
+
+
+	public static void main(String[] args) throws Exception {
+//		Scanner scanner = new Scanner(System.in);
+//		System.out.println("输入需要调用的转换方法:");
+//		System.out.println("convertTxtToVisionmodeldata:输入1");
+//		System.out.println("convertTxtToDam:输入2");
+//		int type = scanner.nextInt();
+//		scanner.reset();
+//		System.out.println("输入源文件路径:");
+//		String srcPath = scanner.next();
+//		System.out.println("输入目标文件路径:");
+//		String targetPath = scanner.next();
+
+		String type = args[0];//类型(1-vision.txt转为vision.modeldata, 2-modeldata.txt转为tieta.dam)
+		String srcPath = args[1];//源文件目录(需要提前源文件放到此目录中再调用方法)
+		String targetPath = args[2];//目标文件路径(目录,转换后文件会放到此目录中,文件名固定为vision.modeldata或tieta.dam)
+
+		if(type.equals("1")){
+			String srcFileName = "vision.txt";
+			String targetFileName = "vision.modeldata";
+			CreateObjUtil.convertTxtToVisionmodeldata(srcPath.concat(File.separator).concat(srcFileName),targetPath.concat(File.separator).concat(targetFileName));
+		}
+		if(type.equals("2")){
+			String srcFileName = "modeldata.txt";
+			String targetFileName = "tieta.dam";
+			CreateObjUtil.convertTxtToDam(srcPath.concat(File.separator).concat(srcFileName),targetPath.concat(File.separator).concat(targetFileName));
+		}
+
+//		scanner.close();
+	}
+
+	/**
+	 * modeldata.txt 转 dam
+	 * @param srcpath 源文件全路径,如D:\test\modeldata.txt
+	 * @param despath 目标文件全路径,如D:\test\tieta.dam
+	 * @throws Exception
+	 */
+	public static void convertTxtToDam(String srcpath,String despath)throws Exception{
+		InputStream inputStream = null;
+		InputStreamReader reader = null;
+		ByteArrayInputStream stream = null;
+		BufferedOutputStream bos = null;
+		BufferedInputStream bis = null;
+		try{
+			BigSceneProto.binary_mesh.Builder builder = BigSceneProto.binary_mesh.newBuilder();
+			inputStream = new FileInputStream(srcpath);
+			reader = new InputStreamReader(inputStream, "ASCII");
+			TextFormat.merge(reader, builder);
+			byte[] buf = builder.build().toByteArray();
+
+			//把序列化后的数据写入本地磁盘
+			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);
+			}
+		}catch (Exception e){
+			log.error("txt转dam出错,srcpath:{}, despath:{}",srcpath, despath);
+			throw e;
+		}finally {
+			if(inputStream != null){
+				inputStream.close();
+			}
+			if(reader != null){
+				reader.close();
+			}
+			if(stream != null){
+				stream.close();
+			}
+			if(bos != null){
+				bos.close();
+			}
+			if(bis != null){
+				bis.close();
+			}
+		}
+
+	}
+
+	/**
+	 * vision.txt 转 vision.modeldata
+	 * @param srcpath 源文件全路径,如D:\test\vision.txt
+	 * @param despath 目标文件全路径,如D:\test\vision.modeldata
+	 * @throws Exception
+	 */
+	public static void convertTxtToVisionmodeldata(String srcpath,String despath)throws Exception {
+
+		Visionmodeldata.NavigationInfo.Builder builder = Visionmodeldata.NavigationInfo.newBuilder();
+		String jsonFormat = transferVisionUuidToIndex(srcpath);
+		JsonFormat.merge(jsonFormat, builder);
+		byte[] buf= builder.build().toByteArray();
+
+		//把序列化后的数据写入本地磁盘
+		try(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);
+			}
+		}
+	}
+
+	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;
+					//log.info(lineTxt);
+				}
+				read.close();
+				return result;
+			}else{
+				return null;
+			}
+		} catch (Exception e) {
+			e.printStackTrace();
+			return null;
+		}
+
+	}
+
+	public static String transferVisionUuidToIndex(String srcPath){
+		String visionJsonStr = readTxtFileToJson(srcPath);
+		JSONObject visionJson = JSON.parseObject(visionJsonStr);
+		JSONArray sweepLocationArr = visionJson.getJSONArray("sweepLocations");
+		Map<String, Integer> uuidIndexMap = new HashMap<>();
+		for (int i = 0; i < sweepLocationArr.size(); i++) {
+			JSONObject sweepLocationObj = (JSONObject)sweepLocationArr.get(i);
+			uuidIndexMap.put(sweepLocationObj.getString("uuid"), i);
+		}
+		for (Object o : sweepLocationArr) {
+			JSONObject sweepLocationObj = (JSONObject)o;
+			JSONArray visibles =  sweepLocationObj.getJSONArray("visibles");
+			int[] visiblesArr = new int[visibles.size()];
+			for(int i = 0; i < visibles.size(); i++){
+				visiblesArr[i] = uuidIndexMap.get(visibles.get(i));
+			}
+			sweepLocationObj.put("visibles", visiblesArr);
+		}
+		return JSON.toJSONString(visionJson);
+	}
+
+}

+ 158 - 0
src/main/java/com/fdkankan/modeldemo/utils/CutImgUtil.java

@@ -0,0 +1,158 @@
+package com.fdkankan.modeldemo.utils;
+
+import cn.hutool.core.collection.CollUtil;
+import cn.hutool.core.collection.ListUtil;
+import cn.hutool.core.io.FileUtil;
+import cn.hutool.log.Log;
+import com.alibaba.fastjson.JSONArray;
+import com.alibaba.fastjson.JSONObject;
+
+import java.io.File;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+public class CutImgUtil {
+
+    public final static String callPath = "/mnt/cutImg/call/";//切图计算目录
+
+    public final static String scene_path = "/mnt/cutImg/scenes/%s/wwwroot/%s";//下载文件路径
+    public final static String numsTxt = "/mnt/cutImg/nums.txt";//场景码文件路径
+
+    public final static String panPath = "/mnt/cutImg/pan/";//虚化全景图路径
+
+    public static void main(String[] args) {
+
+        List<String> nums = FileUtil.readUtf8Lines(numsTxt);
+        for (String num : nums) {
+            System.out.println("切图开始,num:"+num);
+            try {
+                String path = callPath + num;
+                String target = path + "_images";
+                String targetImagesPath = target + "/extras/images/";
+                FileUtil.mkdir(targetImagesPath);
+
+                //复制全景图
+                FileUtil.copyContent(new File(panPath + num), new File(targetImagesPath), true);
+
+                //复制 vision.txt
+                FileUtil.copy(String.format(scene_path, num, "scene_view_data/" + num + "/images/vision.txt") , target + "/extras/vision.txt", true);
+
+                //生成data.json
+                createDataJson(target);
+
+                //调用算法
+                uploadPanoramaHandler(num, target);
+
+                //压缩
+                zip("/mnt/cutImg/scenes/" + num, "/mnt/cutImg/zip/" + num + ".zip");
+
+
+            }catch (Exception e){
+                FileUtil.appendUtf8Lines(ListUtil.toList(num), callPath + "fail.txt");
+            }
+
+            System.out.println("切图结束,num:"+num);
+        }
+    }
+
+    public static void zip(String source, String zipPath) throws Exception {
+        String cmd = "cd " + source + " && zip -r " + zipPath + " *";
+        CmdUtils.callLineSh(cmd);
+    }
+
+    public static void createDataJson(String target){
+        JSONObject floorplanJson = new JSONObject();
+        floorplanJson.put("has_source_images", true);
+        floorplanJson.put("has_vision_txt", true);
+
+        JSONObject dataJson = new JSONObject();
+        dataJson.put("extras", floorplanJson);
+        dataJson.put("split_type", "SPLIT_V8");
+        String skyboxType = "SKYBOX_V14";
+        dataJson.put("skybox_type", skyboxType);
+        FileUtil.writeUtf8String(dataJson.toJSONString(), target + File.separator+"data.json");
+    }
+
+    public static void build3dModel(String folderName, String isModel) throws Exception {
+        System.out.println("开始算法切图");
+        String command = "sudo bash /home/ubuntu/bin/Launcher.sh " + folderName;
+        CmdUtils.callLine(command);
+        System.out.println("算法切图完毕");
+
+    }
+
+    public static void uploadPanoramaHandler(String num, String target) throws Exception {
+
+        String imgViewPath = String.format("scene_view_data/%s/images/", num);
+
+        build3dModel(target , "1");
+
+        String uploadJsonPath= target + File.separator + "results" +File.separator+"upload.json";
+        Thread.sleep(2000);
+        String uploadData = FileUtil.readUtf8String(uploadJsonPath);
+        JSONObject uploadJson = null;
+        JSONArray array = null;
+        if(uploadData!=null) {
+            uploadJson = JSONObject.parseObject(uploadData);
+            array = uploadJson.getJSONArray("upload");
+        }
+        if(array == null){
+            throw new RuntimeException("计算失败,num:" + num);
+        }
+        Map<String, String> map = new HashMap<>();
+        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(target + File.separator + "results" + File.separator + fileName)
+                    .exists()) {
+                throw new Exception(
+                        target + File.separator + "results" + File.separator + fileName + "文件不存在");
+            }
+
+            //high文件夹
+            if (fileJson.getIntValue("clazz") == 3) {
+                map.put(target + File.separator + "results" + File.separator + fileName,
+                        imgViewPath + "pan/high/" + fileName.replace("high/", ""));
+                continue;
+            }
+            //low文件夹
+            if (fileJson.getIntValue("clazz") == 4) {
+                map.put(target + File.separator + "results" + File.separator + fileName,
+                        imgViewPath + "pan/low/" + fileName.replace("low/", ""));
+                continue;
+            }
+
+            //tiles文件夹,亚马逊没有裁剪图片api,不需要上传4k图
+            if (fileJson.getIntValue("clazz") == 5) {
+                map.put(target + File.separator + "results" + File.separator + fileName,
+                        imgViewPath + fileName);
+                continue;
+            }
+
+            //tiles文件夹,亚马逊瓦片图
+            if (fileJson.getIntValue("clazz") == 7) {
+                map.put(target + File.separator + "results" + File.separator + fileName,
+                        imgViewPath + fileName);
+                continue;
+            }
+        }
+
+        if(CollUtil.isNotEmpty(map)) {
+
+            //先删除旧的tiles目录
+            FileUtil.del(String.format(scene_path, num, imgViewPath + "tiles"));
+
+            map.keySet().stream().forEach(v->{
+                FileUtil.copy(v, String.format(scene_path, num, map.get(v)), true);
+            });
+        }
+
+
+
+    }
+
+}

+ 110 - 0
src/main/java/com/fdkankan/modeldemo/utils/FdfsUtil.java

@@ -0,0 +1,110 @@
+package com.fdkankan.modeldemo.utils;
+
+import cn.hutool.core.lang.UUID;
+import cn.hutool.http.HttpRequest;
+import cn.hutool.http.HttpResponse;
+import com.alibaba.fastjson.JSON;
+import com.fdkankan.modeldemo.bean.TietaResBean;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.stereotype.Component;
+
+import java.io.File;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.Map;
+
+@Component
+public class FdfsUtil {
+
+    @Value("${fdfs.address}")
+    private String address;
+
+    @Value("${fdfs.api.getSignature}")
+    private String api_getSignature;
+
+    @Value("${fdfs.api.uploadFile}")
+    private String api_uploadFile;
+
+    @Value("${fdfs.sysCode}")
+    private String sysCode;
+
+    public String getSignature(String nonce, String timestamp){
+        Map<String, String> headers = new HashMap<>();
+        headers.put("timestamp", timestamp);
+        headers.put("nonce", nonce);
+        headers.put("sysCode", sysCode);
+        HttpRequest httpRequest = HttpRequest.post(address.concat(api_getSignature)).addHeaders(headers).timeout(5000);
+        HttpResponse res = httpRequest.execute();
+        String resBody = res.body();
+        res.close();
+        TietaResBean<String> tietaResBean = JSON.parseObject(resBody, TietaResBean.class);
+        String code = tietaResBean.getCode();
+        if(!"000000".equals(code)){
+            throw new RuntimeException("获取签名失败, code:" + code);
+        }
+        return tietaResBean.getData();
+    }
+
+    public Map<String, String> uploadFile(String nonce, String timestamp, String signature, String filePath){
+
+        Map<String, String> headers = new HashMap<>();
+        headers.put("timestamp", timestamp);
+        headers.put("nonce", nonce);
+        headers.put("sysCode", sysCode);
+        headers.put("signature", signature);
+
+        Map<String, Object> test = new HashMap<>();
+        test.put("visibilityLevel", "1003");
+        test.put("file", new File(filePath));
+        test.put("userId", "111111");
+        HttpRequest httpRequest = HttpRequest.post(address.concat(api_uploadFile)).form(test).addHeaders(headers).timeout(60000);
+        HttpResponse res = httpRequest.execute();
+        String resBody = res.body();
+        res.close();
+        TietaResBean<Map<String, String>> tietaResBean = JSON.parseObject(resBody, TietaResBean.class);
+        String code = tietaResBean.getCode();
+        if(!"000000".equals(code)){
+            throw new RuntimeException("上传文件失败, code:" + code);
+        }
+        return tietaResBean.getData();
+    }
+
+    public Map<String, String> uploadFile(String filePath){
+        String nonce = UUID.fastUUID().toString();
+        String timestamp = String.valueOf(new Date().getTime());
+        String signature = getSignature(nonce, timestamp);
+        return uploadFile(nonce, timestamp, signature, filePath);
+    }
+
+    public static void main(String[] args) {
+        Map<String, String> headers = new HashMap<>();
+        headers.put("timestamp", "1719389524320");
+        headers.put("nonce", "123123");
+        headers.put("sysCode", "CT00017");
+        headers.put("signature", "3044022062501c9896a919d81d00216379a84c7d89b2d7315a22f89aee2ce7c1185f656c02206d4694fb685247a289e1c0d11e7492311ef66354c64cd2234fa593e02a635074");
+
+        Map<String, Object> test = new HashMap<>();
+        test.put("visibilityLevel", "1003");
+        test.put("file", new File("D:\\四维时代\\中国铁塔\\数据推送示例\\KK-R4YYV4yIZlT\\images\\4k\\ff54999789b970e64e2845a2337954f9.jpg"));
+        test.put("userId", "111111");
+        HttpRequest httpRequest = HttpRequest.post("http://10.180.22.41:8761/ChinatowerFileService/uploadFile/").form(test).addHeaders(headers).timeout(60000);
+        HttpResponse res = httpRequest.execute();
+        String resBody = res.body();
+        res.close();
+        TietaResBean<Map<String, String>> tietaResBean = JSON.parseObject(resBody, TietaResBean.class);
+        String code = tietaResBean.getCode();
+        if(!"000000".equals(code)){
+            throw new RuntimeException("上传文件失败, code:" + code);
+        }
+        Map<String, String> data = tietaResBean.getData();
+        System.out.println(data);
+    }
+
+
+
+
+
+
+
+
+}

+ 78 - 0
src/main/java/com/fdkankan/modeldemo/utils/StreamGobblerLine.java

@@ -0,0 +1,78 @@
+package com.fdkankan.modeldemo.utils;
+
+import lombok.extern.slf4j.Slf4j;
+
+import java.io.*;
+
+public class StreamGobblerLine extends Thread {
+
+	InputStream is;
+    String type;
+    OutputStream os;
+    Integer lineSize;  // 多少行打印日志一次
+
+    public StreamGobblerLine(InputStream is, String type) {
+        this(is, type, null, null);
+    }
+
+    public StreamGobblerLine(InputStream is, String type, Integer lineSize) {
+        this(is, type, null, lineSize);
+    }
+
+    StreamGobblerLine(InputStream is, String type, OutputStream redirect, Integer lineSize) {
+        this.is = is;
+        this.type = type;
+        this.os = redirect;
+        this.lineSize = lineSize;
+    }
+
+    public void run() {
+        System.out.println("run StreamGobblerLine");
+
+        InputStreamReader isr = null;
+        BufferedReader br = null;
+        PrintWriter pw = null;
+        try {
+            if (os != null)
+                pw = new PrintWriter(os);
+
+            isr = new InputStreamReader(is);
+            br = new BufferedReader(isr);
+            String line=null;
+            int i = 1;
+            while ( (line = br.readLine()) != null) {
+                if (lineSize != null) {
+                    if (i % lineSize == 0) {
+                        System.out.println(type + "," + i +" : >" + line);
+                    }
+                } else {
+                    System.out.println(type + ","  + i +" : >" + line);
+                }
+                i++;
+
+            }
+
+            if (pw != null)
+                pw.flush();
+        } catch (IOException ioe) {
+            ioe.printStackTrace();
+        } finally{
+            try {
+            	if(pw!=null)
+            	{
+            		 pw.close();
+            	}
+            	if(br!=null)
+            	{
+            		br.close();
+            	}
+            	if(isr!=null)
+            	{
+            		isr.close();
+            	}
+            } catch (IOException e) {
+                e.printStackTrace();
+            }
+        }
+    }
+}

+ 38 - 0
src/main/resources/application-test.yml

@@ -0,0 +1,38 @@
+spring:
+  application:
+    name: 4dkankan-center-convert
+  rabbitmq:
+    host: 10.180.22.47
+    port: 5672
+    username: User_CHNTZCGL_ZYAPP_002
+    password: ZYAPP002@VR
+    virtual-host: Vhost_CHNTZCGL_ZYAPP_002
+    connection-timeout: 0
+    listener:
+      simple:
+        prefetch: 1
+        max-concurrency: 1
+        acknowledge-mode: manual #开启消费者手动确认
+    #开启消息投递确认机制
+    publisher-confirm-type: correlated
+  datasource:
+    url: jdbc:oracle:thin:@//8.135.106.227:1521/helowin
+    username: FDKK
+    password: qawsed@123.
+    driver-class-name: oracle.jdbc.OracleDriver
+
+fdfs:
+  sysCode: CT00017
+  address: http://10.180.22.41:8761
+  api:
+    getSignature: /ChinatowerFileService/getSignature
+    uploadFile: /ChinatowerFileService/uploadFile/
+
+
+
+
+
+
+
+
+

+ 3 - 0
src/main/resources/application.yml

@@ -0,0 +1,3 @@
+spring:
+  profiles:
+    active: test

+ 234 - 0
src/main/resources/logback-spring.xml

@@ -0,0 +1,234 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 日志级别从低到高分为TRACE < DEBUG < INFO < WARN < ERROR < FATAL,如果设置为WARN,则低于WARN的信息都不会输出 -->
+<!-- scan:当此属性设置为true时,配置文件如果发生改变,将会被重新加载,默认值为true -->
+<!-- scanPeriod:设置监测配置文件是否有修改的时间间隔,如果没有给出时间单位,默认单位是毫秒。当scan为true时,此属性生效。默认的时间间隔为1分钟。 -->
+<!-- debug:当此属性设置为true时,将打印出logback内部日志信息,实时查看logback运行状态。默认值为false。 -->
+<configuration scan="true" scanPeriod="10 seconds">
+
+	<contextName>logback</contextName>
+	<!-- name的值是变量的名称,value的值时变量定义的值。通过定义的值会被插入到logger上下文中。定义变量后,可以使“${}”来使用变量。 -->
+	<property name="log.path" value="/mnt/backend/4dkankan/convert/logs" />
+
+	<!-- 彩色日志 -->
+	<!-- 彩色日志依赖的渲染类 -->
+	<conversionRule conversionWord="clr" converterClass="org.springframework.boot.logging.logback.ColorConverter" />
+	<conversionRule conversionWord="wex" converterClass="org.springframework.boot.logging.logback.WhitespaceThrowableProxyConverter" />
+	<conversionRule conversionWord="wEx" converterClass="org.springframework.boot.logging.logback.ExtendedWhitespaceThrowableProxyConverter" />
+	<!-- 彩色日志格式 -->
+	<property name="CONSOLE_LOG_PATTERN"
+		value="${CONSOLE_LOG_PATTERN:-%clr(%d{yyyy-MM-dd HH:mm:ss.SSS}){faint} %clr(${LOG_LEVEL_PATTERN:-%5p}) %clr(${PID:- }){magenta} %clr(---){faint} %clr([%15.15t]){faint} %clr(%-40.40logger{39}){cyan} %clr(:){faint} %m%n${LOG_EXCEPTION_CONVERSION_WORD:-%wEx}}" />
+
+	<!--输出到控制台 -->
+	<appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
+		<!--此日志appender是为开发使用,只配置最底级别,控制台输出的日志级别是大于或等于此级别的日志信息 -->
+		<filter class="ch.qos.logback.classic.filter.ThresholdFilter">
+			<level>info</level>
+		</filter>
+		<encoder>
+			<Pattern>${CONSOLE_LOG_PATTERN}</Pattern>
+			<!-- 设置字符集 -->
+			<charset>UTF-8</charset>
+		</encoder>
+	</appender>
+	<!--输出到文件 -->
+
+	<!-- 时间滚动输出 level为 DEBUG 日志 -->
+	<appender name="DEBUG_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
+		<!-- 正在记录的日志文件的路径及文件名 -->
+		<file>${log.path}/log_debug.log</file>
+		<!--日志文件输出格式 -->
+		<encoder>
+			<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n</pattern>
+			<charset>UTF-8</charset> <!-- 设置字符集 -->
+		</encoder>
+		<!-- 日志记录器的滚动策略,按日期,按大小记录 -->
+		<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
+			<!-- 日志归档 -->
+			<fileNamePattern>${log.path}/debug/log-debug-%d{yyyy-MM-dd}.%i.log
+			</fileNamePattern>
+			<timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
+				<maxFileSize>100MB</maxFileSize>
+			</timeBasedFileNamingAndTriggeringPolicy>
+			<!--日志文件保留天数 -->
+			<maxHistory>15</maxHistory>
+		</rollingPolicy>
+		<!-- 此日志文件只记录debug级别的 -->
+		<filter class="ch.qos.logback.classic.filter.LevelFilter">
+			<level>debug</level>
+			<onMatch>ACCEPT</onMatch>
+			<onMismatch>DENY</onMismatch>
+		</filter>
+	</appender>
+
+	<appender name="ASYNC_DEBUG_FILE" class="com.yomahub.tlog.core.enhance.logback.async.AspectLogbackAsyncAppender">
+		<!--默认情况下,当BlockingQueue还有20%容量,他将丢弃TRACE、DEBUG和INFO级别的event,只保留WARN和ERROR级别的event。为了保持所有的events,设置该值为0。-->
+		<discardingThreshold>0</discardingThreshold>
+		<!--queue配置最大容量为256个events。如果队列被填满,应用程序线程被阻止记录新的events,直到工作线程有机会来转发一个或多个events。
+		因此队列深度需要根据业务场景进行相应的测试,做出相应的更改,以达到较好的性能。-->
+		<queueSize>2048</queueSize>
+		<includeCallerData>false</includeCallerData>
+		<appender-ref ref="DEBUG_FILE"/>
+	</appender>
+
+	<!-- 时间滚动输出 level为 INFO 日志 -->
+	<appender name="INFO_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
+		<!-- 正在记录的日志文件的路径及文件名 -->
+		<file>${log.path}/log_info.log</file>
+		<!--日志文件输出格式 -->
+		<encoder>
+			<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n</pattern>
+			<charset>UTF-8</charset>
+		</encoder>
+		<!-- 日志记录器的滚动策略,按日期,按大小记录 -->
+		<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
+			<!-- 每天日志归档路径以及格式 -->
+			<fileNamePattern>${log.path}/info/log-info-%d{yyyy-MM-dd}.%i.log
+			</fileNamePattern>
+			<timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
+				<maxFileSize>100MB</maxFileSize>
+			</timeBasedFileNamingAndTriggeringPolicy>
+			<!--日志文件保留天数 -->
+			<maxHistory>15</maxHistory>
+		</rollingPolicy>
+		<!-- 此日志文件只记录info级别的 -->
+		<filter class="ch.qos.logback.classic.filter.LevelFilter">
+			<level>info</level>
+			<onMatch>ACCEPT</onMatch>
+			<onMismatch>DENY</onMismatch>
+		</filter>
+	</appender>
+
+	<appender name="ASYNC_INFO_FILE" class="com.yomahub.tlog.core.enhance.logback.async.AspectLogbackAsyncAppender">
+		<!--默认情况下,当BlockingQueue还有20%容量,他将丢弃TRACE、DEBUG和INFO级别的event,只保留WARN和ERROR级别的event。为了保持所有的events,设置该值为0。-->
+		<discardingThreshold>0</discardingThreshold>
+		<!--queue配置最大容量为256个events。如果队列被填满,应用程序线程被阻止记录新的events,直到工作线程有机会来转发一个或多个events。
+		因此队列深度需要根据业务场景进行相应的测试,做出相应的更改,以达到较好的性能。-->
+		<queueSize>2048</queueSize>
+		<includeCallerData>false</includeCallerData>
+		<appender-ref ref="INFO_FILE"/>
+	</appender>
+
+	<!-- 时间滚动输出 level为 WARN 日志 -->
+	<appender name="WARN_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
+		<!-- 正在记录的日志文件的路径及文件名 -->
+		<file>${log.path}/log_warn.log</file>
+		<!--日志文件输出格式 -->
+		<encoder>
+			<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n</pattern>
+			<charset>UTF-8</charset> <!-- 此处设置字符集 -->
+		</encoder>
+		<!-- 日志记录器的滚动策略,按日期,按大小记录 -->
+		<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
+			<fileNamePattern>${log.path}/warn/log-warn-%d{yyyy-MM-dd}.%i.log
+			</fileNamePattern>
+			<timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
+				<maxFileSize>100MB</maxFileSize>
+			</timeBasedFileNamingAndTriggeringPolicy>
+			<!--日志文件保留天数 -->
+			<maxHistory>15</maxHistory>
+		</rollingPolicy>
+		<!-- 此日志文件只记录warn级别的 -->
+		<filter class="ch.qos.logback.classic.filter.LevelFilter">
+			<level>warn</level>
+			<onMatch>ACCEPT</onMatch>
+			<onMismatch>DENY</onMismatch>
+		</filter>
+	</appender>
+
+	<appender name="ASYNC_WARN_FILE" class="com.yomahub.tlog.core.enhance.logback.async.AspectLogbackAsyncAppender">
+		<!--默认情况下,当BlockingQueue还有20%容量,他将丢弃TRACE、DEBUG和INFO级别的event,只保留WARN和ERROR级别的event。为了保持所有的events,设置该值为0。-->
+		<discardingThreshold>0</discardingThreshold>
+		<!--queue配置最大容量为256个events。如果队列被填满,应用程序线程被阻止记录新的events,直到工作线程有机会来转发一个或多个events。
+		因此队列深度需要根据业务场景进行相应的测试,做出相应的更改,以达到较好的性能。-->
+		<queueSize>2048</queueSize>
+		<includeCallerData>false</includeCallerData>
+		<appender-ref ref="WARN_FILE"/>
+	</appender>
+
+
+	<!-- 时间滚动输出 level为 ERROR 日志 -->
+	<appender name="ERROR_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
+		<!-- 正在记录的日志文件的路径及文件名 -->
+		<file>${log.path}/log_error.log</file>
+		<!--日志文件输出格式 -->
+		<encoder>
+			<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n</pattern>
+			<charset>UTF-8</charset> <!-- 此处设置字符集 -->
+		</encoder>
+		<!-- 日志记录器的滚动策略,按日期,按大小记录 -->
+		<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
+			<fileNamePattern>${log.path}/error/log-error-%d{yyyy-MM-dd}.%i.log
+			</fileNamePattern>
+			<timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
+				<maxFileSize>100MB</maxFileSize>
+			</timeBasedFileNamingAndTriggeringPolicy>
+			<!--日志文件保留天数 -->
+			<maxHistory>15</maxHistory>
+		</rollingPolicy>
+		<!-- 此日志文件只记录ERROR级别的 -->
+		<filter class="ch.qos.logback.classic.filter.LevelFilter">
+			<level>ERROR</level>
+			<onMatch>ACCEPT</onMatch>
+			<onMismatch>DENY</onMismatch>
+		</filter>
+	</appender>
+
+	<appender name="ASYNC_ERROR_FILE" class="com.yomahub.tlog.core.enhance.logback.async.AspectLogbackAsyncAppender">
+		<!--默认情况下,当BlockingQueue还有20%容量,他将丢弃TRACE、DEBUG和INFO级别的event,只保留WARN和ERROR级别的event。为了保持所有的events,设置该值为0。-->
+		<discardingThreshold>0</discardingThreshold>
+		<!--queue配置最大容量为256个events。如果队列被填满,应用程序线程被阻止记录新的events,直到工作线程有机会来转发一个或多个events。
+		因此队列深度需要根据业务场景进行相应的测试,做出相应的更改,以达到较好的性能。-->
+		<queueSize>2048</queueSize>
+		<includeCallerData>false</includeCallerData>
+		<appender-ref ref="ERROR_FILE"/>
+	</appender>
+
+
+	<!-- <logger>用来设置某一个包或者具体的某一个类的日志打印级别、 以及指定<appender>。<logger>仅有一个name属性, 一个可选的level和一个可选的addtivity属性。 name:用来指定受此logger约束的某一个包或者具体的某一个类。 level:用来设置打印级别,大小写无关:TRACE,
+		DEBUG, INFO, WARN, ERROR, ALL 和 OFF, 还有一个特俗值INHERITED或者同义词NULL,代表强制执行上级的级别。 如果未设置此属性,那么当前logger将会继承上级的级别。 addtivity:是否向上级logger传递打印信息。默认是true。 -->
+	<!--<logger name="org.springframework.web" level="info"/> -->
+	<!--<logger name="org.springframework.scheduling.annotation.ScheduledAnnotationBeanPostProcessor" level="INFO"/> -->
+	<!-- 使用mybatis的时候,sql语句是debug下才会打印,而这里我们只配置了info,所以想要查看sql语句的话,有以下两种操作: 第一种把<root level="info">改成<root level="DEBUG">这样就会打印sql,不过这样日志那边会出现很多其他消息 第二种就是单独给dao下目录配置debug模式,代码如下,这样配置sql语句会打印,其他还是正常info级别: -->
+	<!-- root节点是必选节点,用来指定最基础的日志输出级别,只有一个level属性 level:用来设置打印级别,大小写无关:TRACE, DEBUG, INFO, WARN, ERROR, ALL 和 OFF, 不能设置为INHERITED或者同义词NULL。默认是DEBUG 可以包含零个或多个元素,标识这个appender将会添加到这个logger。 -->
+
+	<root level="info">
+		<appender-ref ref="CONSOLE" />
+		<appender-ref ref="ASYNC_DEBUG_FILE" />
+		<appender-ref ref="ASYNC_INFO_FILE" />
+		<appender-ref ref="ASYNC_WARN_FILE" />
+		<appender-ref ref="ASYNC_ERROR_FILE" />
+	</root>
+
+	<springProfile name="dev">
+		<root level="info">
+			<appender-ref ref="CONSOLE" />
+			<appender-ref ref="ASYNC_DEBUG_FILE" />
+			<appender-ref ref="ASYNC_INFO_FILE" />
+			<appender-ref ref="ASYNC_WARN_FILE" />
+			<appender-ref ref="ASYNC_ERROR_FILE" />
+		</root>
+	</springProfile>
+
+	<springProfile name="test">
+		<root level="info">
+			<appender-ref ref="CONSOLE" />
+			<appender-ref ref="ASYNC_DEBUG_FILE" />
+			<appender-ref ref="ASYNC_INFO_FILE" />
+			<appender-ref ref="ASYNC_WARN_FILE" />
+			<appender-ref ref="ASYNC_ERROR_FILE" />
+		</root>
+	</springProfile>
+
+	<springProfile name="pro">
+		<root level="info">
+			<appender-ref ref="CONSOLE" />
+			<appender-ref ref="ASYNC_DEBUG_FILE" />
+			<appender-ref ref="ASYNC_INFO_FILE" />
+			<appender-ref ref="ASYNC_WARN_FILE" />
+			<appender-ref ref="ASYNC_ERROR_FILE" />
+		</root>
+	</springProfile>
+
+</configuration>
+
+

+ 19 - 0
src/main/resources/mapper/SceneFileMappingMapper.xml

@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="com.fdkankan.modeldemo.mapper.SceneFileMappingMapper">
+
+    <!-- 通用查询映射结果 -->
+    <resultMap id="BaseResultMap" type="com.fdkankan.project.tieta.entity.SceneFileMapping">
+        <id column="ID" property="id" />
+        <result column="NUM" property="num" />
+        <result column="FILEID" property="fileid" />
+        <result column="KEY" property="key" />
+        <result column="URL" property="url" />
+    </resultMap>
+
+    <!-- 通用查询结果列 -->
+    <sql id="Base_Column_List">
+        ID, NUM, FILEID, KEY, URL
+    </sql>
+
+</mapper>

+ 24 - 0
src/main/resources/mapper/SceneMapper.xml

@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="com.fdkankan.modeldemo.mapper.SceneMapper">
+
+    <!-- 通用查询映射结果 -->
+    <resultMap id="BaseResultMap" type="com.fdkankan.project.tieta.entity.Scene">
+        <id column="ID" property="id" />
+        <result column="TITLE" property="title" />
+        <result column="DESCRIPTION" property="description" />
+        <result column="NUM" property="num" />
+        <result column="FLOORLOGOSIZE" property="floorlogosize" />
+        <result column="SCENEKIND" property="scenekind" />
+        <result column="SCENERESOLUTION" property="sceneresolution" />
+        <result column="SCENEFROM" property="scenefrom" />
+        <result column="MODELKIND" property="modelkind" />
+        <result column="FLOORPLANANGLE" property="floorplanangle" />
+    </resultMap>
+
+    <!-- 通用查询结果列 -->
+    <sql id="Base_Column_List">
+        ID, TITLE, DESCRIPTION, NUM, FLOORLOGOSIZE, SCENEKIND, SCENERESOLUTION, SCENEFROM, MODELKIND, FLOORPLANANGLE
+    </sql>
+
+</mapper>