Prechádzať zdrojové kódy

Merge branch 'test' into release

dengsixing 3 rokov pred
rodič
commit
01fc8b6ad8
48 zmenil súbory, kde vykonal 1256 pridanie a 291 odobranie
  1. 0 1
      4dkankan-center-modeling/src/main/java/com/fdkankan/modeling/receiver/RabbitMqListener.java
  2. 8 8
      4dkankan-center-modeling/src/main/resources/bootstrap-dev.yml
  3. 8 8
      4dkankan-center-modeling/src/main/resources/bootstrap-pro.yml
  4. 8 8
      4dkankan-center-modeling/src/main/resources/bootstrap-test.yml
  5. 8 8
      4dkankan-center-platform/src/main/resources/bootstrap-dev.yml
  6. 8 8
      4dkankan-center-platform/src/main/resources/bootstrap-pro.yml
  7. 8 8
      4dkankan-center-platform/src/main/resources/bootstrap-test.yml
  8. 0 1
      4dkankan-center-scene-download/src/main/java/com/fdkankan/download/service/impl/CheckProgressRunnerImpl.java
  9. 2 0
      4dkankan-center-scene-download/src/main/java/com/fdkankan/download/service/impl/SceneDownLoadServiceImpl.java
  10. 89 64
      4dkankan-center-scene-download/src/main/java/com/fdkankan/download/service/impl/SceneDownloadHandlerServiceImpl.java
  11. 0 19
      4dkankan-center-scene-download/src/main/resources/bootstrap-dev.yml
  12. 4 24
      4dkankan-center-scene-download/src/main/resources/bootstrap-pro.yml
  13. 4 25
      4dkankan-center-scene-download/src/main/resources/bootstrap-test.yml
  14. 3 2
      4dkankan-center-scene-download/src/main/resources/logback-spring.xml
  15. 87 0
      4dkankan-center-scene/src/main/java/com/fdkankan/scene/Interceptor/CheckCooperationPermitAspect.java
  16. 14 0
      4dkankan-center-scene/src/main/java/com/fdkankan/scene/annotation/CheckCooperationPermit.java
  17. 29 0
      4dkankan-center-scene/src/main/java/com/fdkankan/scene/bean/PointBean.java
  18. 33 0
      4dkankan-center-scene/src/main/java/com/fdkankan/scene/bean/RequestSceneProV4.java
  19. 20 0
      4dkankan-center-scene/src/main/java/com/fdkankan/scene/bean/SegmentBean.java
  20. 18 0
      4dkankan-center-scene/src/main/java/com/fdkankan/scene/bean/VertexBean.java
  21. 29 0
      4dkankan-center-scene/src/main/java/com/fdkankan/scene/bean/WallBean.java
  22. 13 0
      4dkankan-center-scene/src/main/java/com/fdkankan/scene/callback/FdkkMiniReqErrorCallback.java
  23. 0 33
      4dkankan-center-scene/src/main/java/com/fdkankan/scene/controller/SceneController.java
  24. 64 6
      4dkankan-center-scene/src/main/java/com/fdkankan/scene/controller/SceneEditController.java
  25. 3 3
      4dkankan-center-scene/src/main/java/com/fdkankan/scene/controller/TestController.java
  26. 79 0
      4dkankan-center-scene/src/main/java/com/fdkankan/scene/controller/V3Controller.java
  27. 6 0
      4dkankan-center-scene/src/main/java/com/fdkankan/scene/entity/SceneEditInfoExt.java
  28. 20 0
      4dkankan-center-scene/src/main/java/com/fdkankan/scene/httpclient/FdkankanMiniClient.java
  29. 4 0
      4dkankan-center-scene/src/main/java/com/fdkankan/scene/service/ISceneEditInfoService.java
  30. 1 1
      4dkankan-center-scene/src/main/java/com/fdkankan/scene/service/ISceneEditService.java
  31. 2 0
      4dkankan-center-scene/src/main/java/com/fdkankan/scene/service/ISceneUpgradeToV4Service.java
  32. 7 1
      4dkankan-center-scene/src/main/java/com/fdkankan/scene/service/ISceneUploadService.java
  33. 151 3
      4dkankan-center-scene/src/main/java/com/fdkankan/scene/service/impl/BuildScenePostServiceImpl.java
  34. 238 4
      4dkankan-center-scene/src/main/java/com/fdkankan/scene/service/impl/SceneEditInfoServiceImpl.java
  35. 57 36
      4dkankan-center-scene/src/main/java/com/fdkankan/scene/service/impl/SceneEditServiceImpl.java
  36. 10 10
      4dkankan-center-scene/src/main/java/com/fdkankan/scene/service/impl/SceneProServiceImpl.java
  37. 47 5
      4dkankan-center-scene/src/main/java/com/fdkankan/scene/service/impl/SceneUpgradeToV4Service.java
  38. 32 4
      4dkankan-center-scene/src/main/java/com/fdkankan/scene/service/impl/SceneUploadServiceImpl.java
  39. 7 0
      4dkankan-center-scene/src/main/java/com/fdkankan/scene/vo/SceneAuthVO.java
  40. 5 0
      4dkankan-center-scene/src/main/java/com/fdkankan/scene/vo/SceneInfoVO.java
  41. 2 0
      4dkankan-center-scene/src/main/java/com/fdkankan/scene/vo/UpgradeToV4ParamVO.java
  42. 23 0
      4dkankan-center-scene/src/main/java/com/fdkankan/scene/vo/UploadContentParamVO.java
  43. 1 1
      4dkankan-center-scene/src/main/resources/bootstrap-test.yml
  44. 29 0
      4dkankan-common/src/main/java/com/fdkankan/common/model/SSOUser.java
  45. 12 0
      4dkankan-common/src/main/java/com/fdkankan/common/user/SSOLoginHelper.java
  46. 25 0
      4dkankan-common/src/main/java/com/fdkankan/common/user/SSOLoginStore.java
  47. 38 0
      4dkankan-common/src/main/java/com/fdkankan/common/util/WebUtil.java
  48. BIN
      document/git分支管理说明.docx

+ 0 - 1
4dkankan-center-modeling/src/main/java/com/fdkankan/modeling/receiver/RabbitMqListener.java

@@ -331,7 +331,6 @@ public class RabbitMqListener {
                 //如果是重复计算,没有走到计算逻辑,不需要上传日志文件
                 buildLog.setLogDetailPath(prefixAli+ buildLogPath + "console.log");
             }
-            buildLog.setUpdateTime(Calendar.getInstance().getTime());
             buildLog.setBuildStatus(buildStatus.code());
             buildLog.setCameraType(Integer.parseInt(buildSceneResult.getCameraType()));
             buildLogService.updateById(buildLog);

+ 8 - 8
4dkankan-center-modeling/src/main/resources/bootstrap-dev.yml

@@ -42,11 +42,11 @@ spring:
           management:
             context-path: ${server.servlet.context-path}/actuator
 
-management:
-  endpoints:
-    web:
-      exposure:
-        include: '*'
-  endpoint:
-    health:
-      show-details: ALWAYS
+#management:
+#  endpoints:
+#    web:
+#      exposure:
+#        include: '*'
+#  endpoint:
+#    health:
+#      show-details: ALWAYS

+ 8 - 8
4dkankan-center-modeling/src/main/resources/bootstrap-pro.yml

@@ -38,11 +38,11 @@ spring:
           management:
             context-path: ${server.servlet.context-path}/actuator
 
-management:
-  endpoints:
-    web:
-      exposure:
-        include: '*'
-  endpoint:
-    health:
-      show-details: ALWAYS
+#management:
+#  endpoints:
+#    web:
+#      exposure:
+#        include: '*'
+#  endpoint:
+#    health:
+#      show-details: ALWAYS

+ 8 - 8
4dkankan-center-modeling/src/main/resources/bootstrap-test.yml

@@ -38,11 +38,11 @@ spring:
           management:
             context-path: ${server.servlet.context-path}/actuator
 
-management:
-  endpoints:
-    web:
-      exposure:
-        include: '*'
-  endpoint:
-    health:
-      show-details: ALWAYS
+#management:
+#  endpoints:
+#    web:
+#      exposure:
+#        include: '*'
+#  endpoint:
+#    health:
+#      show-details: ALWAYS

+ 8 - 8
4dkankan-center-platform/src/main/resources/bootstrap-dev.yml

@@ -47,11 +47,11 @@ feign:
   httpclient:
     connection-timeout: 200000
 
-management:
-  endpoints:
-    web:
-      exposure:
-        include: '*'
-  endpoint:
-    health:
-      show-details: ALWAYS
+#management:
+#  endpoints:
+#    web:
+#      exposure:
+#        include: '*'
+#  endpoint:
+#    health:
+#      show-details: ALWAYS

+ 8 - 8
4dkankan-center-platform/src/main/resources/bootstrap-pro.yml

@@ -47,14 +47,14 @@ feign:
   httpclient:
     connection-timeout: 200000
 
-management:
-  endpoints:
-    web:
-      exposure:
-        include: '*'
-  endpoint:
-    health:
-      show-details: ALWAYS
+#management:
+#  endpoints:
+#    web:
+#      exposure:
+#        include: '*'
+#  endpoint:
+#    health:
+#      show-details: ALWAYS
 
 tlog:
   enable-invoke-time-print: true

+ 8 - 8
4dkankan-center-platform/src/main/resources/bootstrap-test.yml

@@ -47,11 +47,11 @@ feign:
   httpclient:
     connection-timeout: 200000
 
-management:
-  endpoints:
-    web:
-      exposure:
-        include: '*'
-  endpoint:
-    health:
-      show-details: ALWAYS
+#management:
+#  endpoints:
+#    web:
+#      exposure:
+#        include: '*'
+#  endpoint:
+#    health:
+#      show-details: ALWAYS

+ 0 - 1
4dkankan-center-scene-download/src/main/java/com/fdkankan/download/service/impl/CheckProgressRunnerImpl.java

@@ -54,7 +54,6 @@ public class CheckProgressRunnerImpl implements CommandLineRunner {
                 return JSON.toJSONString(DownLoadTaskBean.builder().num(num).type("local").build());
             }).collect(Collectors.toList());
 
-            // TODO: 2022/2/22 这里上线是要改成RedisKey.DOWNLOAD_TASK
             //从新入队
             redisUtil.lLeftPushAll(RedisKey.SCENE_DOWNLOADS_TASK_V4, taskList);
 

+ 2 - 0
4dkankan-center-scene-download/src/main/java/com/fdkankan/download/service/impl/SceneDownLoadServiceImpl.java

@@ -10,6 +10,7 @@ import com.fdkankan.redis.util.RedisUtil;
 import java.util.Objects;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.beans.factory.annotation.Value;
+import org.springframework.cloud.context.config.annotation.RefreshScope;
 import org.springframework.stereotype.Service;
 
 /**
@@ -20,6 +21,7 @@ import org.springframework.stereotype.Service;
  * @author dengsixing
  * @since 2022/2/22
  **/
+@RefreshScope
 @Service
 public class SceneDownLoadServiceImpl implements ISceneDownLoadService {
 

+ 89 - 64
4dkankan-center-scene-download/src/main/java/com/fdkankan/download/service/impl/SceneDownloadHandlerServiceImpl.java

@@ -4,27 +4,24 @@ import cn.hutool.core.collection.CollUtil;
 import cn.hutool.core.collection.ConcurrentHashSet;
 import cn.hutool.core.exceptions.ExceptionUtil;
 import cn.hutool.core.util.StrUtil;
-import cn.hutool.json.JSON;
 import cn.hutool.json.JSONObject;
 import cn.hutool.json.JSONUtil;
-import com.fdkankan.common.constant.DownloadStatus;
+import com.fdkankan.common.bean.DownLoadProgressBean;
+import com.fdkankan.common.bean.DownLoadTaskBean;
 import com.fdkankan.common.constant.SceneDownloadProgressStatus;
 import com.fdkankan.common.constant.ServerCode;
 import com.fdkankan.common.constant.UploadFilePath;
 import com.fdkankan.common.response.ResultData;
 import com.fdkankan.common.util.FileUtils;
 import com.fdkankan.download.bean.CurrentDownloadNumUtil;
+import com.fdkankan.download.bean.ImageType;
+import com.fdkankan.download.bean.ImageTypeDetail;
 import com.fdkankan.fyun.constant.StorageType;
 import com.fdkankan.fyun.oss.UploadToOssUtil;
-import com.fdkankan.platform.api.feign.PlatformUserClient;
 import com.fdkankan.redis.constant.RedisKey;
 import com.fdkankan.redis.util.RedisUtil;
-import com.fdkankan.common.bean.DownLoadProgressBean;
-import com.fdkankan.common.bean.DownLoadTaskBean;
 import com.fdkankan.scene.api.dto.SceneInfoDTO;
 import com.fdkankan.scene.api.feign.SceneUserSceneClient;
-import com.fdkankan.download.bean.ImageType;
-import com.fdkankan.download.bean.ImageTypeDetail;
 import com.google.common.collect.Lists;
 import java.io.File;
 import java.io.FileInputStream;
@@ -33,17 +30,22 @@ import java.net.URLEncoder;
 import java.util.ArrayList;
 import java.util.Calendar;
 import java.util.HashMap;
-import java.util.HashSet;
 import java.util.List;
 import java.util.Map;
 import java.util.Objects;
 import java.util.Set;
+import java.util.concurrent.Callable;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.Future;
+import java.util.concurrent.atomic.AtomicInteger;
 import java.util.stream.Collectors;
 import lombok.extern.slf4j.Slf4j;
 import lombok.var;
 import org.apache.tools.zip.ZipOutputStream;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.beans.factory.annotation.Value;
+import org.springframework.cloud.context.config.annotation.RefreshScope;
 import org.springframework.scheduling.annotation.Async;
 import org.springframework.stereotype.Service;
 import org.springframework.web.client.RestTemplate;
@@ -56,12 +58,13 @@ import org.springframework.web.client.RestTemplate;
  * @author dengsixing
  * @since 2022/2/22
  **/
+@RefreshScope
 @Slf4j
 @Service
 public class SceneDownloadHandlerServiceImpl {
 
-    @Autowired
-    private PlatformUserClient platformUserClient;
+    //    @Autowired
+//    private PlatformUserClient platformUserClient;
     @Autowired
     private SceneUserSceneClient sceneUserSceneClient;
 
@@ -76,18 +79,16 @@ public class SceneDownloadHandlerServiceImpl {
 
     @Value("${path.zip-root}")
     private String wwwroot;
-//    private static final String[] prefixArr = new String[]{
-//        "data/data%s/",
-//        "voice/voice%s/",
-//        "video/video%s/",
-//        "images/images%s/"
-//    };
+
+    @Value("${zip.nThreads}")
+    private int zipNthreads;
 
     private static final String[] prefixArr = new String[]{
         UploadFilePath.DATA_VIEW_PATH,
         UploadFilePath.VOICE_VIEW_PATH,
         UploadFilePath.VIDEOS_VIEW_PATH,
-        UploadFilePath.IMG_VIEW_PATH
+        UploadFilePath.IMG_VIEW_PATH,
+        UploadFilePath.USER_VIEW_PATH,
     };
 
     private static final List<ImageType> imageTypes = Lists.newArrayList();
@@ -152,17 +153,11 @@ public class SceneDownloadHandlerServiceImpl {
     public void downloadHandler(DownLoadTaskBean downLoadTaskBean) throws Exception{
 
         String num = downLoadTaskBean.getNum();
-        Long userId = downLoadTaskBean.getUserId();
-
         //zip包路径
         String zipPath = null;
 
-        //代码文件路径
-        //String v3localPath = "/downloads/v3local/";
-//        String v3localPath = "F:\\downloads\\v3local\\";
-
         try {
-            Set<String> cacheKeys = new HashSet<>();
+            Set<String> cacheKeys = new ConcurrentHashSet<>();
 
             Map<String, List<String>> allFiles = this.getAllFiles(num, v3localPath);
             List<String> ossFilePaths = allFiles.get("ossFilePaths");
@@ -170,12 +165,13 @@ public class SceneDownloadHandlerServiceImpl {
 
             //key总个数
             int total = ossFilePaths.size() + v3localFilePaths.size();
-            int count = 0;
+            AtomicInteger count = new AtomicInteger(0);
             //定义压缩包
-            //            zipPath = "/downloads/scenes/" + num + ".zip";
-//            zipPath = "F:\\downloads\\scenes\\" + num + ".zip";
             zipPath = String.format(this.zipLocalFormat, num);
             File zipFile = new File(zipPath);
+            if(!zipFile.getParentFile().exists()){
+                zipFile.getParentFile().mkdirs();
+            }
             ZipOutputStream out = new ZipOutputStream(zipFile);
 
             JSONObject getInfoJson = this.zipGetInfoJson(out, this.wwwroot, num);
@@ -194,11 +190,17 @@ public class SceneDownloadHandlerServiceImpl {
             }
 
 
+            long start = Calendar.getInstance().getTimeInMillis();
             //固定文件写入
-            count = this.zipLocalFiles(out, v3localFilePaths, v3localPath, num, count, total);
+            this.zipLocalFiles(out, v3localFilePaths, v3localPath, num, count, total);
+            long end1 = Calendar.getInstance().getTimeInMillis();
+            log.info("打包固定文件耗时, num:{}, time:{}", num, end1 - start);
 
             //oss文件写入
-            count = this.zipOssFiles(out, ossFilePaths, num, count, total, resolution, imagesVersion, cacheKeys);
+            this.zipOssFiles(out, ossFilePaths, num, count, total, resolution, imagesVersion, cacheKeys);
+            long end2 = Calendar.getInstance().getTimeInMillis();
+            log.info("打包oss文件耗时, num:{}, time:{}", num, end2 - end1);
+
 
             //写入启动命令
             this.zipBat(out, num);
@@ -207,23 +209,27 @@ public class SceneDownloadHandlerServiceImpl {
 
             //上传压缩包
             String uploadPath = String.format(this.zipOssFormat, num);
-            uploadToOssUtil.upload(zipPath, uploadPath);
+            uploadToOssUtil.uploadBySh(zipPath, uploadPath);
 
             //更新进度100
             String url = this.publicUrl + uploadPath;
             this.updateProgress(null, num, SceneDownloadProgressStatus.DOWNLOAD_SUCCESS.code(), url);
 
+            // TODO: 2022/5/24 v3 停止后要开启-----------------------start
             //更新用户场景已下载次数
-            platformUserClient.updateDownloadNum(userId, 1);
-
-            //更新下载log状态为成功
-            sceneUserSceneClient.updateSceneDownloadLog(num, DownloadStatus.SUCCESS.code(), url, null);
+//            platformUserClient.updateDownloadNum(userId, 1);
+//
+//            //更新下载log状态为成功
+//            sceneUserSceneClient.updateSceneDownloadLog(num, DownloadStatus.SUCCESS.code(), url, null);
+            // TODO: 2022/5/24 v3 停止后要开启-----------------------end
 
         }catch (Exception e){
             //更新进度为下载失败
             this.updateProgress( null, num, SceneDownloadProgressStatus.DOWNLOAD_FAILED.code(), null);
             //更新下载log状态为成功
-            sceneUserSceneClient.updateSceneDownloadLog(num, DownloadStatus.FAILD.code(), null, ExceptionUtil.stacktraceToString(e));
+            // TODO: 2022/5/24 v3 停止后要开启-----------------------start
+//            sceneUserSceneClient.updateSceneDownloadLog(num, DownloadStatus.FAILD.code(), null, ExceptionUtil.stacktraceToString(e));
+            // TODO: 2022/5/24 v3 停止后要开启-----------------------send
             throw e;
         }finally {
             if(StrUtil.isNotBlank(zipPath)){
@@ -233,28 +239,53 @@ public class SceneDownloadHandlerServiceImpl {
         }
     }
 
-    private int zipOssFiles(ZipOutputStream out, List<String> ossFilePaths, String num, int count, int total, String resolution, int imagesVersion, Set<String> cacheKeys) throws Exception{
-        String imageNumPath = "images" + num;
+    private void zipOssFiles(ZipOutputStream out, List<String> ossFilePaths, String num, AtomicInteger count,
+        int total, String resolution, int imagesVersion, Set<String> cacheKeys) throws Exception{
+        String imageNumPath = String.format(UploadFilePath.IMG_VIEW_PATH, num);
+        ExecutorService executorService = Executors.newFixedThreadPool(this.zipNthreads);
+        List<Future> futureList = new ArrayList<>();
         for (String filePath : ossFilePaths) {
-            if(filePath.contains(imageNumPath + "/panorama/panorama_edit/")){
-                //如果是编辑目录,只需要更新进度,不需要放进压缩包
-                this.updateProgress(new BigDecimal(++count).divide(new BigDecimal(total), 6, BigDecimal.ROUND_HALF_UP), 
-                    num, SceneDownloadProgressStatus.DOWNLOADING.code(), null);
-                continue;
-            }else if((filePath.contains(imageNumPath + "/panorama/") && filePath.contains("tiles/" + resolution)) || filePath.contains(imageNumPath + "/tiles/" + resolution + "/")) {
-                this.processImage(filePath, out, resolution, imagesVersion, cacheKeys);
-            }else{
-                this.ProcessFiles(filePath, out, this.wwwroot, cacheKeys);
-            }
+            Callable<Boolean> call = new Callable() {
+                @Override
+                public Boolean call() throws Exception {
+                    zipOssFilesHandler(out, num, count, total, resolution,
+                        imagesVersion, cacheKeys,filePath, imageNumPath);
+                    return true;
+                }
+            };
+            futureList.add(executorService.submit(call));
+        }
+        //这里一定要加阻塞,不然会导致oss文件还没打包好,主程序已经结束返回了
+        for (Future future : futureList) {
+            future.get();
+        }
+    }
 
-            //更新进度
-            this.updateProgress(new BigDecimal(++count).divide(new BigDecimal(total), 6, BigDecimal.ROUND_HALF_UP),  
-                num, SceneDownloadProgressStatus.DOWNLOAD_COMPRESSING.code(), null);
+    private void zipOssFilesHandler(ZipOutputStream out, String num,
+        AtomicInteger count, int total, String resolution,
+        int imagesVersion, Set<String> cacheKeys,
+        String filePath, String imageNumPath) throws Exception{
+
+        //更新进度
+        this.updateProgress(new BigDecimal(count.incrementAndGet()).divide(new BigDecimal(total), 6, BigDecimal.ROUND_HALF_UP),
+            num, SceneDownloadProgressStatus.DOWNLOADING.code(), null);
+
+        //某个目录不需要打包
+        if(filePath.contains(imageNumPath + "panorama/panorama_edit/"))
+            return;
+
+        //切图
+        if((filePath.contains(imageNumPath + "panorama/") && filePath.contains("tiles/" + resolution))
+            || filePath.contains(imageNumPath + "tiles/" + resolution + "/")) {
+            this.processImage(filePath, out, resolution, imagesVersion, cacheKeys);
+            return;
         }
-        return count;
+
+        //其他文件打包
+        this.ProcessFiles(filePath, out, this.wwwroot, cacheKeys);
     }
 
-    private int zipLocalFiles(ZipOutputStream out, List<String> v3localFilePaths, String v3localPath, String num, int count, int total) throws Exception{
+    private void zipLocalFiles(ZipOutputStream out, List<String> v3localFilePaths, String v3localPath, String num, AtomicInteger count, int total) throws Exception{
         for (String v3localFilePath : v3localFilePaths) {
             try (FileInputStream in = new FileInputStream(new File(v3localFilePath));){
                 this.zipInputStream(out, v3localFilePath.replace(v3localPath, ""), in);
@@ -263,12 +294,11 @@ public class SceneDownloadHandlerServiceImpl {
             }
             //更新进度
             this.updateProgress(
-                new BigDecimal(++count).divide(new BigDecimal(total), 6, BigDecimal.ROUND_HALF_UP),
+                new BigDecimal(count.incrementAndGet()).divide(new BigDecimal(total), 6, BigDecimal.ROUND_HALF_UP),
                 num, SceneDownloadProgressStatus.DOWNLOAD_COMPRESSING.code(), null);
         }
         //写入code.txt
         this.zipBytes(out, "code.txt", num.getBytes());
-        return count;
     }
 
     private void zipBat(ZipOutputStream out, String num) throws Exception{
@@ -329,7 +359,7 @@ public class SceneDownloadHandlerServiceImpl {
         getInfoJson.set("needKey", 0);
         getInfoJson.set("sceneKey","");
         //写入getInfo.json
-        String getInfoJsonPath = root + "data/data"+ num + "/getInfo.json";
+        String getInfoJsonPath = root + String.format(UploadFilePath.DATA_VIEW_PATH, num) + "getInfo.json";
         this.zipBytes(out, getInfoJsonPath, getInfoJson.toString().getBytes());
         return getInfoJson;
     }
@@ -368,7 +398,6 @@ public class SceneDownloadHandlerServiceImpl {
                     );
                 }
             }
-
             for (ImageTypeDetail item : items) {
                 String par = "?x-oss-process=image/resize,m_lfit,w_" + imageType.getSize() + "/crop,w_512,h_512,x_" + item.getX() + ",y_" + item.getY();
                 if(StorageType.AWS.code().equals(uploadType)){
@@ -391,8 +420,7 @@ public class SceneDownloadHandlerServiceImpl {
                     continue;
                 }
                 imgKeys.add(fky);
-                byte[] bytes = FileUtils.getBytesFromUrl(url);
-                this.zipBytes(out, wwwroot + fky, bytes);
+                this.zipBytes(out, wwwroot + fky, FileUtils.getBytesFromUrl(url));
             }
 
         }
@@ -405,7 +433,6 @@ public class SceneDownloadHandlerServiceImpl {
         }
         cacheKeys.add(key);
         String url = this.resourceUrl + key + "?t=" + Calendar.getInstance().getTimeInMillis();
-        byte[] data = null;
         if(key.contains("hot.json") || key.contains("link-scene.json")){
             String content = FileUtils.getStringFromUrl(url);
 
@@ -414,12 +441,10 @@ public class SceneDownloadHandlerServiceImpl {
                 .replace("https://spc.html","spc.html")
                 .replace("https://smobile.html", "smobile.html");
 
-            data = content.getBytes();
+            zipBytes(out, prefix + key, content.getBytes());
         }else{
-            data = FileUtils.getBytesFromUrl(url);
+            zipBytes(out, prefix + key, FileUtils.getBytesFromUrl(url));
         }
-
-        zipBytes(out, prefix + key, data);
     }
 
 
@@ -465,7 +490,7 @@ public class SceneDownloadHandlerServiceImpl {
         }
     }
 
-    public void zipBytes(ZipOutputStream out, String key, byte[] bytes) throws Exception {
+    public synchronized void zipBytes(ZipOutputStream out, String key, byte[] bytes) throws Exception {
         out.putNextEntry(new org.apache.tools.zip.ZipEntry(key));
         out.write(bytes);
     }

+ 0 - 19
4dkankan-center-scene-download/src/main/resources/bootstrap-dev.yml

@@ -31,25 +31,6 @@ spring:
       discovery:
         server-addr: 192.168.0.47:8848
         namespace: 4dkankan-dev
-path:
-  v3school: /downloads/v3local/
-  zip-root: wwwroot/
-  zip-local: /downloads/scenes/%s.zip
-  zip-oss: downloads/scenes/%s.zip
-
-download:
-  config:
-    server-url: https://test.4dkankan.com/
-    public-url: https://4dkk.4dage.com/
-    resource-url: https://4dkankan.oss-cn-shenzhen.aliyuncs.com/
-#    server-url: https://eur.4dkankan.com/
-#    public-url: https://eurs3.4dkankan.com/
-#    resource-url: https://eurs3.4dkankan.com/
-    exe-name: start-browser.bat
-    exe-content: | # | 表示不转义特殊字符
-      taskkill /f /t /im http.exe
-      start http://127.0.0.1:9000/spc.html?m=%s
-      http.exe -nc -p 9000 -r wwwroot
 
 
 

+ 4 - 24
4dkankan-center-scene-download/src/main/resources/bootstrap-pro.yml

@@ -8,9 +8,9 @@ spring:
   cloud:
     nacos:
       config:
-        server-addr: 192.168.0.47:8848
+        server-addr: 172.18.157.42:8848
         file-extension: yaml
-        namespace: 4dkankan-dev
+        namespace: 4dkankan-pro
         extension-configs:
           - data-id: 4dkankan-center-scene-download.yaml
             group: DEFAULT_GROUP
@@ -29,28 +29,8 @@ spring:
             group: DEFAULT_GROUP
             refresh: true
       discovery:
-        server-addr: 192.168.0.47:8848
-        namespace: public
-path:
-  v3school: /downloads/v3local/
-  zip-root: wwwroot/
-  zip-local: /downloads/scenes/%s.zip
-  zip-oss: downloads/scenes/%s.zip
-
-download:
-  config:
-    server-url: https://test.4dkankan.com/
-    public-url: https://4dkk.4dage.com/
-    resource-url: https://4dkankan.oss-cn-shenzhen.aliyuncs.com/
-#    server-url: https://eur.4dkankan.com/
-#    public-url: https://eurs3.4dkankan.com/
-#    resource-url: https://eurs3.4dkankan.com/
-    exe-name: start-browser.bat
-    exe-content: | # | 表示不转义特殊字符
-      taskkill /f /t /im http.exe
-      start http://127.0.0.1:9000/spc.html?m=%s
-      http.exe -nc -p 9000 -r wwwroot
-
+        server-addr: 172.18.157.42:8848
+        namespace: 4dkankan-pro
 
 
 

+ 4 - 25
4dkankan-center-scene-download/src/main/resources/bootstrap-test.yml

@@ -8,16 +8,16 @@ spring:
   cloud:
     nacos:
       config:
-        server-addr: 172.18.156.39:8848
+        server-addr: 120.24.144.164:8848
         file-extension: yaml
-        namespace: 4dkankan-dev
+        namespace: 4dkankan-test
         extension-configs:
           - data-id: 4dkankan-center-scene-download.yaml
             group: DEFAULT_GROUP
             refresh: true
         shared-configs:
 
-          - data-id: common-redis-config.yaml
+          - data-id: common-redis-config-52.yaml
             group: DEFAULT_GROUP
             refresh: true
 
@@ -29,28 +29,7 @@ spring:
             group: DEFAULT_GROUP
             refresh: true
       discovery:
-        server-addr: 172.18.156.39:8848
+        server-addr: 120.24.144.164:8848
         namespace: 4dkankan-test
-path:
-  v3school: /downloads/v3local/
-  zip-root: wwwroot/
-  zip-local: /downloads/scenes/%s.zip
-  zip-oss: downloads/scenes/%s.zip
-
-download:
-  config:
-    server-url: https://test.4dkankan.com/
-    public-url: https://4dkk.4dage.com/
-    resource-url: https://4dkankan.oss-cn-shenzhen.aliyuncs.com/
-#    server-url: https://eur.4dkankan.com/
-#    public-url: https://eurs3.4dkankan.com/
-#    resource-url: https://eurs3.4dkankan.com/
-    exe-name: start-browser.bat
-    exe-content: | # | 表示不转义特殊字符
-      taskkill /f /t /im http.exe
-      start http://127.0.0.1:9000/spc.html?m=%s
-      http.exe -nc -p 9000 -r wwwroot
-
-
 
 

+ 3 - 2
4dkankan-center-scene-download/src/main/resources/logback-spring.xml

@@ -4,10 +4,11 @@
 <!-- scanPeriod:设置监测配置文件是否有修改的时间间隔,如果没有给出时间单位,默认单位是毫秒。当scan为true时,此属性生效。默认的时间间隔为1分钟。 -->
 <!-- debug:当此属性设置为true时,将打印出logback内部日志信息,实时查看logback运行状态。默认值为false。 -->
 <configuration scan="true" scanPeriod="10 seconds">
-
+	<springProperty scope="context" name="LOG_PATH" source="logging.path"/>
+	<define name="hostName" class = "com.fdkankan.common.config.LogPathHostNameProperty"/>
 	<contextName>logback</contextName>
 	<!-- name的值是变量的名称,value的值时变量定义的值。通过定义的值会被插入到logger上下文中。定义变量后,可以使“${}”来使用变量。 -->
-	<property name="log.path" value="/data/4dkankan/logs/4dkankan_center_scene_download" />
+	<property name="log.path" value="${LOG_PATH}/download" />
 
 	<!-- 彩色日志 -->
 	<!-- 彩色日志依赖的渲染类 -->

+ 87 - 0
4dkankan-center-scene/src/main/java/com/fdkankan/scene/Interceptor/CheckCooperationPermitAspect.java

@@ -0,0 +1,87 @@
+package com.fdkankan.scene.Interceptor;
+
+import cn.hutool.core.collection.CollUtil;
+import cn.hutool.core.util.StrUtil;
+import com.fdkankan.common.constant.ErrorCode;
+import com.fdkankan.common.constant.ServerCode;
+import com.fdkankan.common.exception.BusinessException;
+import com.fdkankan.common.user.SSOLoginHelper;
+import com.fdkankan.common.util.WebUtil;
+import com.fdkankan.redis.constant.RedisKey;
+import com.fdkankan.redis.util.RedisUtil;
+import com.fdkankan.scene.entity.ScenePlus;
+import com.fdkankan.scene.service.IScenePlusService;
+import java.io.IOException;
+import java.util.Map;
+import java.util.Objects;
+import javax.servlet.http.HttpServletRequest;
+import lombok.extern.log4j.Log4j2;
+import org.aspectj.lang.JoinPoint;
+import org.aspectj.lang.annotation.Aspect;
+import org.aspectj.lang.annotation.Before;
+import org.aspectj.lang.annotation.Pointcut;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.core.annotation.Order;
+import org.springframework.stereotype.Component;
+import org.springframework.web.context.request.RequestContextHolder;
+import org.springframework.web.context.request.ServletRequestAttributes;
+
+@Log4j2
+@Aspect
+@Component
+@Order(101)
+public class CheckCooperationPermitAspect {
+
+	@Autowired
+	private SSOLoginHelper ssoLoginHelper;
+	@Autowired
+	private RedisUtil redisUtil;
+	@Autowired
+	private IScenePlusService scenePlusService;
+
+
+	@Pointcut("@annotation(com.fdkankan.scene.annotation.CheckCooperationPermit)")
+	public void checkCooperationPermit() {
+	}
+
+	/**
+	 * 前置通知 用于判断用户协作场景是否有协作权限
+	 *
+	 * @param joinPoint
+	 *            切点
+	 * @throws IOException
+	 */
+	@Before("checkCooperationPermit()")
+	public void doBefore(JoinPoint joinPoint) throws Exception {
+		HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
+		// 读取session中的用户
+		com.fdkankan.common.model.SSOUser user = ssoLoginHelper.loginCheckV3(request.getHeader("token"));
+		if(Objects.isNull(user)){
+			throw new BusinessException(ErrorCode.TOKEN_NOT_FOUND);
+		}
+		String num = WebUtil.getNum(joinPoint, request);
+		if(StrUtil.isEmpty(num)){
+			throw new BusinessException(ErrorCode.PARAM_REQUIRED);
+		}
+
+
+		//判断是不是场景原用户,如果是,跳出
+        ScenePlus scenePlus= scenePlusService.getScenePlusByNum(num);
+		if(Objects.isNull(scenePlus)){
+			throw new BusinessException(ErrorCode.FAILURE_CODE_5005);
+		}
+        if(scenePlus.getUserId().equals(user.getId())){
+            return;
+        }
+
+        //如果不是用户自己的场景,判断是否有协作权限
+        String userId = redisUtil.hget(RedisKey.SCENE_COOPERATION_NUM_USERID, num);
+        if(StrUtil.isEmpty(userId)){
+            throw new BusinessException(ErrorCode.FAILURE_CODE_5014);
+        }
+        if(!userId.equals(String.valueOf(user.getId()))){
+            throw new BusinessException(ErrorCode.FAILURE_CODE_5014);
+        }
+	}
+
+}

+ 14 - 0
4dkankan-center-scene/src/main/java/com/fdkankan/scene/annotation/CheckCooperationPermit.java

@@ -0,0 +1,14 @@
+package com.fdkankan.scene.annotation;
+
+import java.lang.annotation.Documented;
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+@Target({ElementType.PARAMETER, ElementType.METHOD})
+@Retention(RetentionPolicy.RUNTIME)
+@Documented
+public @interface CheckCooperationPermit {
+    String description() default "";
+}

+ 29 - 0
4dkankan-center-scene/src/main/java/com/fdkankan/scene/bean/PointBean.java

@@ -0,0 +1,29 @@
+package com.fdkankan.scene.bean;
+
+import java.io.Serializable;
+import java.util.Map;
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+import lombok.ToString;
+
+/**
+ * <p>
+ * TODO
+ * </p>
+ *
+ * @author dengsixing
+ * @since 2022/6/8
+ **/
+@Data
+@Builder
+@NoArgsConstructor
+@AllArgsConstructor
+@ToString
+public class PointBean implements Serializable {
+    private String vectorId;
+    private float x;
+    private float y;
+    private Map<String, String> parent;
+}

+ 33 - 0
4dkankan-center-scene/src/main/java/com/fdkankan/scene/bean/RequestSceneProV4.java

@@ -0,0 +1,33 @@
+package com.fdkankan.scene.bean;
+
+import com.google.firebase.database.annotations.NotNull;
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+/**
+ * <p>
+ * TODO
+ * </p>
+ *
+ * @author dengsixing
+ * @since 2022/4/24
+ **/
+@Data
+@Builder
+@NoArgsConstructor
+@AllArgsConstructor
+public class RequestSceneProV4 {
+
+    @NotNull
+    private Long id;
+
+    private String webSite;
+
+    private String thumb;
+
+    private String sceneName;
+
+
+}

+ 20 - 0
4dkankan-center-scene/src/main/java/com/fdkankan/scene/bean/SegmentBean.java

@@ -0,0 +1,20 @@
+package com.fdkankan.scene.bean;
+
+import lombok.Data;
+
+/**
+ * <p>
+ * TODO
+ * </p>
+ *
+ * @author dengsixing
+ * @since 2022/6/8
+ **/
+@Data
+public class SegmentBean {
+    private int id;
+    private int a;
+    private int b;
+    private String startPointId;
+    private String endPointId;
+}

+ 18 - 0
4dkankan-center-scene/src/main/java/com/fdkankan/scene/bean/VertexBean.java

@@ -0,0 +1,18 @@
+package com.fdkankan.scene.bean;
+
+import lombok.Data;
+
+/**
+ * <p>
+ * TODO
+ * </p>
+ *
+ * @author dengsixing
+ * @since 2022/6/8
+ **/
+@Data
+public class VertexBean {
+    private int id;
+    private float x;
+    private float y;
+}

+ 29 - 0
4dkankan-center-scene/src/main/java/com/fdkankan/scene/bean/WallBean.java

@@ -0,0 +1,29 @@
+package com.fdkankan.scene.bean;
+
+import java.io.Serializable;
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+import lombok.ToString;
+
+/**
+ * <p>
+ * TODO
+ * </p>
+ *
+ * @author dengsixing
+ * @since 2022/6/8
+ **/
+@Data
+@Builder
+@NoArgsConstructor
+@AllArgsConstructor
+@ToString
+public class WallBean implements Serializable {
+    private String vectorId;
+    private String start;
+    private String end;
+    private String[] children;
+    private Double width;
+}

+ 13 - 0
4dkankan-center-scene/src/main/java/com/fdkankan/scene/callback/FdkkMiniReqErrorCallback.java

@@ -1,5 +1,7 @@
 package com.fdkankan.scene.callback;
 
+import com.alibaba.fastjson.JSON;
+import com.alibaba.fastjson.JSONObject;
 import com.dtflys.forest.callback.OnError;
 import com.dtflys.forest.callback.OnSuccess;
 import com.dtflys.forest.exceptions.ForestRuntimeException;
@@ -7,6 +9,7 @@ import com.dtflys.forest.http.ForestRequest;
 import com.dtflys.forest.http.ForestResponse;
 import com.fdkankan.common.constant.ServerCode;
 import com.fdkankan.common.exception.BusinessException;
+import com.fdkankan.common.response.Result;
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.stereotype.Component;
 
@@ -24,6 +27,16 @@ public class FdkkMiniReqErrorCallback implements OnError {
     @Override
     public void onError(ForestRuntimeException e, ForestRequest forestRequest,
         ForestResponse forestResponse) {
+        JSONObject jsonObject = JSON.parseObject(forestResponse.getContent());
+        Integer status = jsonObject.getInteger("status");
+        if(status != null && status == 500){
+            log.error("v3接口报错,status:{},error:{}", status, jsonObject.getString("error"));
+            throw new BusinessException(ServerCode.SYSTEM_ERROR);
+        }
+        Result result = JSON.parseObject(forestResponse.getContent(), Result.class);
+        if(result.getCode() != ServerCode.SUCCESS.code()){
+            throw new BusinessException(result.getCode(), result.getMsg());
+        }
         log.error("跨服务请求失败!", e);
         throw new BusinessException(ServerCode.FEIGN_REQUEST_FAILD);
     }

+ 0 - 33
4dkankan-center-scene/src/main/java/com/fdkankan/scene/controller/SceneController.java

@@ -207,39 +207,6 @@ public class SceneController extends BaseController{
         return sceneProService.getScenesBySnCode(snCode,getToken());
     }
 
-
-    /**
-     * <p>
-            场景升级
-            此接口用于V3\V4系统并存过渡期,场景升级v4做数据迁移用,待V3关闭可以删除
-     * </p>
-     * @author dengsixing
-     * @date 2022/4/21
-     * @return com.fdkankan.common.response.ResultData
-     **/
-    @PostMapping(value = "/upgradeToV4")
-    public ResultData upgradeToV4(@RequestBody @Validated UpgradeToV4ParamVO param){
-        ResultData resultData = sceneUpgradeToV4Service.upgradeToV4(param);
-        return resultData;
-    }
-
-    /**
-     * <p>
-            场景升级进度查询
-            此接口用于V3\V4系统并存过渡期,场景升级v4做数据迁移用,待V3关闭可以删除
-     * </p>
-     * @author dengsixing
-     * @date 2022/4/21
-     * @return com.fdkankan.common.response.ResultData
-     **/
-    @GetMapping(value = "/getUpgradeToV4Progress")
-    public ResultData getUpgradeToV4Progress(@RequestParam(value = "num") String num){
-        ResultData resultData = sceneUpgradeToV4Service.getUpgradeToV4Progress(num);
-        return resultData;
-    }
-
-
-
 //    /**
 //     * 获取场景详情
 //     */

+ 64 - 6
4dkankan-center-scene/src/main/java/com/fdkankan/scene/controller/SceneEditController.java

@@ -4,6 +4,7 @@ import com.fdkankan.common.constant.ErrorCode;
 import com.fdkankan.common.constant.SceneInfoReqType;
 import com.fdkankan.common.controller.BaseController;
 import com.fdkankan.common.exception.BusinessException;
+import com.fdkankan.scene.annotation.CheckCooperationPermit;
 import com.fdkankan.scene.service.ISceneEditInfoService;
 import com.fdkankan.scene.service.ISceneEditService;
 import com.fdkankan.scene.service.ISceneProService;
@@ -60,6 +61,7 @@ public class SceneEditController extends BaseController {
      * @param param
      * @return com.fdkankan.common.response.ResultData
      **/
+    @CheckCooperationPermit
     @PostMapping(value = "/base/save")
     public SceneEditInfoVO saveScene(@RequestBody @Validated SceneEditInfoParamVO param){
         return sceneEditInfoService.saveScene(param);
@@ -74,6 +76,7 @@ public class SceneEditController extends BaseController {
      * @param param
      * @return com.fdkankan.common.response.ResultData
      **/
+    @CheckCooperationPermit
     @PostMapping(value = "/publicScene")
     public ResultData publicScene(@RequestBody @Validated SceneEditInfoParamVO param) throws Exception {
         return sceneEditInfoService.publicScene(param);
@@ -190,6 +193,7 @@ public class SceneEditController extends BaseController {
      * @param param
      * @return com.fdkankan.common.response.ResultData
      **/
+    @CheckCooperationPermit
     @PostMapping(value = "/saveInitialPage")
     public ResultData saveInitialPage(@RequestBody @Validated FileNameAndDataParamVO param) throws Exception {
         return sceneProService.saveInitialPage(param);
@@ -246,6 +250,7 @@ public class SceneEditController extends BaseController {
      * @param param
      * @return com.fdkankan.common.response.ResultData
      **/
+    @CheckCooperationPermit
     @PostMapping(value = "/tag/save")
     public ResultData saveTag(@RequestBody @Validated SaveTagsParamVO param) throws Exception {
         return sceneProService.addOrUpdateTag(param);
@@ -260,6 +265,7 @@ public class SceneEditController extends BaseController {
      * @param param
      * @return com.fdkankan.common.response.ResultData
      **/
+    @CheckCooperationPermit
     @PostMapping(value = "/tag/delete")
     public ResultData deleteTag(@RequestBody @Validated DeleteHotParamVO param) throws Exception {
         return sceneProService.deleteTag(param);
@@ -279,6 +285,7 @@ public class SceneEditController extends BaseController {
      * @param param
      * @return com.fdkankan.common.response.ResultData
      **/
+    @CheckCooperationPermit
     @PostMapping(value = "/icons/delete")
     public ResultData deleteIcons(@RequestBody @Validated DeleteHotIconParamVO param) throws Exception {
         return sceneProService.deleteIcons(param);
@@ -407,6 +414,7 @@ public class SceneEditController extends BaseController {
      * @param param
      * @return com.fdkankan.common.response.ResultData
      **/
+    @CheckCooperationPermit
     @PostMapping(value = "/saveRoam")
     public ResultData saveRoam(@RequestBody @Validated BaseDataParamVO param) throws Exception {
         return sceneProService.saveRoam(param);
@@ -416,6 +424,7 @@ public class SceneEditController extends BaseController {
      * 保存热点可见性的数据
      * @return
      */
+    @CheckCooperationPermit
     @PostMapping(value = "/saveTagsVisible")
     public ResultData saveTagsVisible(@RequestBody @Validated SaveTagsVisibleParamVO param) throws Exception {
         return sceneProService.saveTagsVisible(param);
@@ -518,6 +527,7 @@ public class SceneEditController extends BaseController {
     /**
      * 肖安需求,下载场景obj和贴图
      */
+    @CheckCooperationPermit
     @PostMapping(value = "/downloadModel")
     public ResultData downloadTexData(@RequestParam("num") String num) throws Exception {
         return sceneProService.downloadTexData(num);
@@ -529,6 +539,7 @@ public class SceneEditController extends BaseController {
      * @return
      */
 //    @SystemControllerLog(description = "上传修改后的obj和贴图")
+    @CheckCooperationPermit
     @PostMapping(value = "/uploadModel")
     public ResultData uploadObjAndImg(@RequestParam("num") String num, @RequestParam("file") MultipartFile file) throws Exception {
         return sceneProService.uploadObjAndImg(num, file);
@@ -673,6 +684,7 @@ public class SceneEditController extends BaseController {
      * @param param
      * @return com.fdkankan.common.response.ResultData
      **/
+    @CheckCooperationPermit
     @PostMapping(value = "/cad/save")
     public ResultData saveCad(@RequestBody @Validated BaseDataParamVO param) throws Exception{
         return sceneEditInfoService.saveCad(param);
@@ -687,6 +699,7 @@ public class SceneEditController extends BaseController {
      * @param num
      * @return
      **/
+    @CheckCooperationPermit
     @PostMapping(value = "/cad/reset")
     public ResultData resetCad(@RequestParam(value = "num") String num){
         return sceneEditInfoService.resetCad(num);
@@ -698,9 +711,9 @@ public class SceneEditController extends BaseController {
      * </p>
      * @author dengsixing
      * @date 2022/2/16
-     * @param num
      * @return
      **/
+    @CheckCooperationPermit
     @PostMapping(value = "/cad/rename")
     public ResultData renameCad(@RequestBody @Validated RenameCadParamVO param) throws IOException {
         return sceneEditInfoService.renameCad(param);
@@ -717,7 +730,7 @@ public class SceneEditController extends BaseController {
 
     /**
      * <p>
-            批量上传全景照片
+            上传全景图
      * </p>
      * @author dengsixing
      * @date 2022/2/16
@@ -725,6 +738,7 @@ public class SceneEditController extends BaseController {
      * @param file
      * @return java.util.List<java.lang.String>
      **/
+    @CheckCooperationPermit
     @PostMapping(value = "/uploadPanorama")
     public ResultData uploadPanorama(@RequestParam(value = "num") String num,
         @RequestParam("file") MultipartFile file) throws Exception {
@@ -739,6 +753,7 @@ public class SceneEditController extends BaseController {
      * @date 2022/2/16
      * @return java.util.List<java.lang.String>
      **/
+    @CheckCooperationPermit
     @PostMapping(value = "/downloadPanorama")
     public ResultData downloadPanorama(@RequestBody @Validated FileParamVO param) throws Exception {
         return sceneEditInfoService.downloadPanorama(param);
@@ -753,6 +768,7 @@ public class SceneEditController extends BaseController {
      * @param param
      * @return com.fdkankan.common.response.ResultData
      **/
+    @CheckCooperationPermit
     @PostMapping(value = "/video/box/save")
     public ResultData saveVideoBox(@RequestBody @Validated FileNameAndDataParamVO param) throws Exception {
         return sceneEditInfoService.saveVideoBox(param);
@@ -767,6 +783,7 @@ public class SceneEditController extends BaseController {
      * @param param
      * @return com.fdkankan.common.response.ResultData
      **/
+    @CheckCooperationPermit
     @PostMapping(value = "/video/box/delete")
     public ResultData deleteVideoBox(@RequestBody @Validated DeleteSidParamVO param) throws Exception {
         return sceneEditInfoService.deleteVideoBox(param);
@@ -781,6 +798,7 @@ public class SceneEditController extends BaseController {
      * @param param
      * @return com.fdkankan.common.response.ResultData
      **/
+    @CheckCooperationPermit
     @PostMapping(value = "/photo/box/save")
     public ResultData savePhotoBox(@RequestBody @Validated BaseDataParamVO param) throws Exception {
         return sceneEditInfoService.saveBoxPhoto(param);
@@ -795,6 +813,7 @@ public class SceneEditController extends BaseController {
      * @param param
      * @return com.fdkankan.common.response.ResultData
      **/
+    @CheckCooperationPermit
     @PostMapping(value = "/photo/box/delete")
     public ResultData deletePhotoBox(@RequestBody @Validated DeleteSidParamVO param) throws Exception {
         return sceneEditInfoService.deleteBoxPhoto(param);
@@ -810,6 +829,7 @@ public class SceneEditController extends BaseController {
      * @param param
      * @return com.fdkankan.scene.vo.DownloadVO
      **/
+    @CheckCooperationPermit
     @PostMapping(value = "downloadBallScreenVideo")
     public DownloadVO downloadBallScreenVideo(@RequestBody @Validated BallScreenVideoParamVO param){
         return sceneEditInfoService.downloadBallScreenVideo(param);
@@ -826,6 +846,7 @@ public class SceneEditController extends BaseController {
      * @param file
      * @return com.fdkankan.common.response.ResultData
      **/
+    @CheckCooperationPermit
     @PostMapping(value = "uploadBallScreenVideo")
     public ResultData uploadBallScreenVideo(
             @RequestParam("num") String num,
@@ -842,15 +863,29 @@ public class SceneEditController extends BaseController {
      * files     文件
      * num 场景码
      * type 操作类型 0添加,1替换
+     * uploadPath 上传路径,此字段为扩展字段,前端可自定义上传路径,注意是完全的文件路径
      */
+    @CheckCooperationPermit
     @RequestMapping(value = "/upload/files", method = RequestMethod.POST)
     public String uploads(@RequestParam(value = "base64",required = false) String base64,
         @RequestParam(value = "fileName",required = false) String fileName,
         @RequestParam(value = "bizType",required = false) String bizType,
         @RequestParam(value = "files",required = false) MultipartFile[] files,
         @RequestParam(value = "num",required = false) String num,
-        @RequestParam(value = "type",required = false,defaultValue = "1") Integer type) throws Exception {
-        return sceneUploadService.uploads(base64,fileName,bizType,files,num,type,getToken());
+        @RequestParam(value = "type",required = false,defaultValue = "1") Integer type,
+        @RequestParam(value = "uploadPath",required = false) String uploadPath) throws Exception {
+        return sceneUploadService.uploads(base64,fileName,bizType,files,num,type,getToken(),uploadPath);
+    }
+
+    /**
+     * 用户自定义上传文本内容上传
+     * @param param
+     * @return
+     * @throws Exception
+     */
+    @RequestMapping(value = "/upload/content", method = RequestMethod.POST)
+    public String uploadContent(@RequestBody @Validated UploadContentParamVO param) throws Exception {
+        return sceneUploadService.uploadContent(param);
     }
 
     /**
@@ -862,6 +897,7 @@ public class SceneEditController extends BaseController {
      * @param paramVO
      * @return com.fdkankan.common.response.ResultData
      **/
+    @CheckCooperationPermit
     @PostMapping("/delete/file")
     public ResultData delete(@RequestBody @Validated DeleteFileParamVO paramVO) throws Exception{
         return sceneUploadService.delete(paramVO);
@@ -870,6 +906,7 @@ public class SceneEditController extends BaseController {
     /**
      * 场景同步
      */
+    @CheckCooperationPermit
     @PostMapping(value = "/sceneSync")
     public ResultData sceneSync(
         @RequestParam("num") String num,
@@ -887,9 +924,10 @@ public class SceneEditController extends BaseController {
      * @return
      * @throws Exception
      */
+    @CheckCooperationPermit
     @PostMapping(value = "/getAuth")
-    public SceneAuthVO getAuth(BaseSceneParamVO param) throws Exception{
-        return sceneEditService.getAuth(param);
+    public SceneAuthVO getAuth(@RequestParam("num") String num) throws Exception{
+        return sceneEditService.getAuth(num, this.getToken());
     }
 
     /**
@@ -915,16 +953,36 @@ public class SceneEditController extends BaseController {
      * @return
      * @throws Exception
      */
+    @CheckCooperationPermit
     @PostMapping(value = "/tour/save")
     public ResultData saveTour(@RequestBody @Validated BaseDataParamVO param) throws Exception{
         return sceneEditService.saveTour(param);
     }
 
+    /**
+     * 删除导览
+     * @param param
+     * @return
+     * @throws Exception
+     */
+    @CheckCooperationPermit
     @PostMapping(value = "/tour/delete")
     public ResultData deleteTour(@RequestBody @Validated BaseSceneParamVO param) throws Exception{
         return sceneEditService.deleteTour(param);
     }
 
+    /**
+     * 添加马赛克
+     * @param param
+     * @return
+     * @throws Exception
+     */
+    @CheckCooperationPermit
+    @PostMapping(value = "/mosaics/add")
+    public ResultData addMosaics(@RequestBody @Validated BaseDataParamVO param) throws Exception{
+        return sceneEditInfoService.addMosaics(param);
+    }
+
 
 
 

+ 3 - 3
4dkankan-center-scene/src/main/java/com/fdkankan/scene/controller/TestController.java

@@ -85,10 +85,10 @@ public class TestController extends BaseController {
 
 
 
-    @PostMapping("/test")
-    public ResultData test(String path) throws Exception {
+    @GetMapping("/test")
+    public ResultData test() throws Exception {
 
-        uploadToOssUtil.uploadBySh(path, "test_dsx/bin.tar");
+//        uploadToOssUtil.uploadBySh(path, "test_dsx/bin.tar");
 
         return ResultData.ok();
 

+ 79 - 0
4dkankan-center-scene/src/main/java/com/fdkankan/scene/controller/V3Controller.java

@@ -0,0 +1,79 @@
+package com.fdkankan.scene.controller;
+
+import com.fdkankan.common.controller.BaseController;
+import com.fdkankan.common.response.ResultData;
+import com.fdkankan.scene.service.ISceneEditInfoService;
+import com.fdkankan.scene.service.ISceneUpgradeToV4Service;
+import com.fdkankan.scene.vo.UpgradeToV4ParamVO;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.RestController;
+
+/**
+ * <p>
+ * TODO
+ * </p>
+ *
+ * @author dengsixing
+ * @since 2022/5/20
+ **/
+@RestController
+@RequestMapping("/service-v3/scene")
+public class V3Controller extends BaseController {
+
+    @Autowired
+    private ISceneUpgradeToV4Service sceneUpgradeToV4Service;
+    @Autowired
+    private ISceneEditInfoService sceneEditInfoService;
+
+    /**
+     * <p>
+     场景升级
+     此接口用于V3\V4系统并存过渡期,场景升级v4做数据迁移用,待V3关闭可以删除
+     * </p>
+     * @author dengsixing
+     * @date 2022/4/21
+     * @return com.fdkankan.common.response.ResultData
+     **/
+    @PostMapping(value = "/upgradeToV4")
+    public ResultData upgradeToV4(@RequestBody @Validated UpgradeToV4ParamVO param){
+        ResultData resultData = sceneUpgradeToV4Service.upgradeToV4(param);
+        return resultData;
+    }
+
+    /**
+     * <p>
+     场景升级进度查询
+     此接口用于V3\V4系统并存过渡期,场景升级v4做数据迁移用,待V3关闭可以删除
+     * </p>
+     * @author dengsixing
+     * @date 2022/4/21
+     * @return com.fdkankan.common.response.ResultData
+     **/
+    @GetMapping(value = "/getUpgradeToV4Progress")
+    public ResultData getUpgradeToV4Progress(@RequestParam(value = "num") String num){
+        ResultData resultData = sceneUpgradeToV4Service.getUpgradeToV4Progress(num);
+        return resultData;
+    }
+
+    /**
+     * <p>
+     查询场景scenejson
+     此接口用于V3\V4系统并存过渡期,待V3关闭可以删除
+     * </p>
+     * @author dengsixing
+     * @date 2022/4/21
+     * @return com.fdkankan.common.response.ResultData
+     **/
+    @GetMapping(value = "/getSceneViewInfo")
+    public ResultData getSceneViewInfo(@RequestParam(value = "num") String num){
+        return sceneUpgradeToV4Service.getSceneViewInfo(num);
+    }
+
+
+}

+ 6 - 0
4dkankan-center-scene/src/main/java/com/fdkankan/scene/entity/SceneEditInfoExt.java

@@ -56,6 +56,12 @@ public class SceneEditInfoExt {
     private Integer tours;
 
     /**
+     * mosaics数据
+     */
+    @TableField("mosaics")
+    private String mosaics;
+
+    /**
      * 创建时间
      */
     @TableField("create_time")

+ 20 - 0
4dkankan-center-scene/src/main/java/com/fdkankan/scene/httpclient/FdkankanMiniClient.java

@@ -2,6 +2,7 @@ package com.fdkankan.scene.httpclient;
 
 import com.dtflys.forest.annotation.Body;
 import com.dtflys.forest.annotation.Get;
+import com.dtflys.forest.annotation.Header;
 import com.dtflys.forest.annotation.Post;
 import com.dtflys.forest.annotation.Retry;
 import com.dtflys.forest.annotation.Success;
@@ -11,10 +12,14 @@ import com.dtflys.forest.callback.OnSuccess;
 import com.dtflys.forest.http.ForestResponse;
 import com.fdkankan.common.response.Result;
 import com.fdkankan.scene.bean.CameraBean;
+import com.fdkankan.scene.bean.RequestSceneProV4;
 import com.fdkankan.scene.bean.UserIncrementBean;
+//import com.fdkankan.scene.callback.FdkkMiniReqSuccessCondition;
 import com.fdkankan.scene.callback.FdkkMiniReqSuccessCondition;
+import com.fdkankan.scene.entity.SceneProV3;
 import java.io.File;
 import java.io.InputStream;
+import java.util.Map;
 import org.springframework.beans.factory.annotation.Value;
 import org.springframework.web.bind.annotation.RequestParam;
 import org.springframework.web.multipart.MultipartFile;
@@ -44,4 +49,19 @@ public interface FdkankanMiniClient {
     @Retry(maxRetryCount = "3", maxRetryInterval = "100")
     Result<CameraBean> getCameraByCameraId(@Var("url") String url, OnSuccess<Result> onSuccess, OnError onError);
 
+    @Get(url="{url}")
+    @Retry(maxRetryCount = "3", maxRetryInterval = "100")
+    Result<SceneProV3> getSceneProByNum(@Var("url") String url, OnSuccess<Result> onSuccess, OnError onError);
+
+    @Post(url="{url}")
+    @Retry(maxRetryCount = "3", maxRetryInterval = "100")
+    Result<Map<String, Object>> getIsLogin(@Var("url") String url, @Header("token") String token, OnSuccess<Result> onSuccess, OnError onError);
+
+    @Post(
+        url = "${url}",
+        contentType = "application/json"
+    )
+    @Retry(maxRetryCount = "3", maxRetryInterval = "100")
+    Result upgradeToV4ResultSync(@Var("url") String url, @Body RequestSceneProV4 param, OnSuccess<Result> onSuccess, OnError onError);
+
 }

+ 4 - 0
4dkankan-center-scene/src/main/java/com/fdkankan/scene/service/ISceneEditInfoService.java

@@ -6,6 +6,8 @@ import com.fdkankan.scene.entity.SceneEditInfo;
 import com.baomidou.mybatisplus.extension.service.IService;
 import com.fdkankan.scene.vo.*;
 import java.io.IOException;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.RequestBody;
 import org.springframework.web.multipart.MultipartFile;
 
 /**
@@ -64,6 +66,8 @@ public interface ISceneEditInfoService extends IService<SceneEditInfo> {
 
     ResultData checkKey(SceneCheckKeyParamVO param) throws Exception;
 
+    ResultData addMosaics(@RequestBody @Validated BaseDataParamVO param) throws Exception;
+
 
 
 

+ 1 - 1
4dkankan-center-scene/src/main/java/com/fdkankan/scene/service/ISceneEditService.java

@@ -19,7 +19,7 @@ import org.springframework.web.bind.annotation.RequestBody;
  **/
 public interface ISceneEditService {
 
-    SceneAuthVO getAuth(BaseSceneParamVO param) throws Exception;
+    SceneAuthVO getAuth(String num, String token) throws Exception;
 
     ResultData locales(LocalesParamVO param) throws Exception;
 

+ 2 - 0
4dkankan-center-scene/src/main/java/com/fdkankan/scene/service/ISceneUpgradeToV4Service.java

@@ -17,4 +17,6 @@ public interface ISceneUpgradeToV4Service {
 
     ResultData getUpgradeToV4Progress(String num);
 
+    ResultData getSceneViewInfo(String num);
+
 }

+ 7 - 1
4dkankan-center-scene/src/main/java/com/fdkankan/scene/service/ISceneUploadService.java

@@ -4,6 +4,9 @@ import com.baomidou.mybatisplus.extension.service.IService;
 import com.fdkankan.common.response.ResultData;
 import com.fdkankan.scene.entity.SceneUpload;
 import com.fdkankan.scene.vo.DeleteFileParamVO;
+import com.fdkankan.scene.vo.UploadContentParamVO;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.RequestBody;
 import org.springframework.web.multipart.MultipartFile;
 
 /**
@@ -16,7 +19,10 @@ import org.springframework.web.multipart.MultipartFile;
  */
 public interface ISceneUploadService extends IService<SceneUpload> {
 
-    String uploads(String imgData, String fileName,String blzType,MultipartFile[] files, String sceneCode, Integer type,String token) throws Exception;
+    String uploads(String imgData, String fileName,String blzType,MultipartFile[] files,
+        String sceneCode, Integer type,String token, String uploadPath) throws Exception;
 
     ResultData delete(DeleteFileParamVO param) throws Exception;
+
+    String uploadContent(UploadContentParamVO param) throws Exception;
 }

+ 151 - 3
4dkankan-center-scene/src/main/java/com/fdkankan/scene/service/impl/BuildScenePostServiceImpl.java

@@ -44,7 +44,11 @@ import com.fdkankan.push.PushMsgUtil;
 import com.fdkankan.rabbitmq.bean.BuildSceneResultMqMessage;
 import com.fdkankan.redis.constant.RedisKey;
 import com.fdkankan.redis.util.RedisUtil;
+import com.fdkankan.scene.bean.PointBean;
 import com.fdkankan.scene.bean.SceneJsonBean;
+import com.fdkankan.scene.bean.SegmentBean;
+import com.fdkankan.scene.bean.VertexBean;
+import com.fdkankan.scene.bean.WallBean;
 import com.fdkankan.scene.entity.SceneEditControls;
 import com.fdkankan.scene.entity.SceneEditInfo;
 import com.fdkankan.scene.entity.SceneEditInfoExt;
@@ -55,7 +59,6 @@ import com.fdkankan.scene.entity.ScenePro;
 import com.fdkankan.scene.entity.SceneProExt;
 import com.fdkankan.scene.service.IBuildSceneDTService;
 import com.fdkankan.scene.service.IBuildScenePostService;
-import com.fdkankan.scene.service.IBuildScenePreService;
 import com.fdkankan.scene.service.ISceneEditControlsService;
 import com.fdkankan.scene.service.ISceneEditInfoExtService;
 import com.fdkankan.scene.service.ISceneEditInfoService;
@@ -66,10 +69,11 @@ import com.fdkankan.scene.service.ISceneProExtService;
 import com.fdkankan.scene.service.ISceneProService;
 import com.fdkankan.scene.service.ISceneService;
 import com.fdkankan.scene.vo.SceneEditControlsVO;
-import com.sun.org.apache.bcel.internal.generic.RETURN;
 import java.io.File;
 import java.io.IOException;
+import java.nio.charset.StandardCharsets;
 import java.util.Calendar;
+import java.util.Collection;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
@@ -104,6 +108,8 @@ public class BuildScenePostServiceImpl implements IBuildScenePostService {
     private String ossType;
     @Value("${oss.prefix.ali}")
     private String prefixAli;
+    @Value("${oss.bucket:4dkankan}")
+    private String bucket;
 
     @Autowired
     ISceneService sceneService;
@@ -224,8 +230,13 @@ public class BuildScenePostServiceImpl implements IBuildScenePostService {
 
             Map<String, String> newUploadFiles = this.uploadFileMapHandler(sceneCode, cameraType, uploadFiles);
 
+            // TODO: 2022/5/26 下载全景图采用打包本地文件的方式,这里应该是不需要上传到oss了,暂时保留代码并注释掉------start
             //上传计算结果中的caches/images和caches/videos
-            this.uploadCaches(sceneCode, uploadFiles, path);
+//            this.uploadCaches(sceneCode, uploadFiles, path);
+            // TODO: 2022/5/26 下载全景图采用打包本地文件的方式,这里应该是不需要上传到oss了,暂时保留代码并注释掉------end
+
+            //上传全景图俯视图
+            this.uploadFloorCad(path, sceneCode, newUploadFiles);
 
             //上传文件
             uploadToOssUtil.uploadMulFiles(newUploadFiles);
@@ -235,6 +246,9 @@ public class BuildScenePostServiceImpl implements IBuildScenePostService {
             //拷贝部分文件到编辑目录,用于用户编辑
             this.copyToEditDir(sceneCode);
 
+            //生成houseTypejson并上传
+            this.uploadHouseTypeJson(sceneCode);
+
 //            //上传日志文件
 //            buildScenePreService.uploadLogFile(sceneCode, sceneProExt.getDataSource());
 
@@ -255,6 +269,25 @@ public class BuildScenePostServiceImpl implements IBuildScenePostService {
         }
     }
 
+    private void uploadFloorCad(String path, String num, Map<String, String> uploadFiles){
+
+        //户型图上传
+        String  userEditPath = UploadFilePath.USER_EDIT_PATH + "floor-cad-%s.%s";
+        String  userViewPath = UploadFilePath.USER_VIEW_PATH + "floor-cad-%s.%s";
+        String floorCadPath = path + "/results/floorplan_cad";
+        List<String> floorCadList = FileUtil.getFileList(floorCadPath);
+        if(CollUtil.isNotEmpty(floorCadList)){
+            floorCadList.stream().forEach(str->{
+                String substring = str.substring(str.lastIndexOf(File.separator) + 1);
+                String[] arr = substring.split("floor");
+                String[] arr2 = arr[1].split("\\.");
+                uploadFiles.put(str, String.format(userEditPath, num, arr2[0], arr2[1]));
+                uploadFiles.put(str, String.format(userViewPath, num, arr2[0], arr2[1]));
+            });
+        }
+
+    }
+
     private void writeSceneJson(String num, JSONObject videosJson, SceneEditInfo sceneEditInfo,SceneEditInfoExt sceneEditInfoExt,
         SceneEditControls sceneEditControls, ScenePlus scenePlus, ScenePlusExt scenePlusExt, boolean arrearCap)  throws Exception{
         String sceneJsonKey = String.format(UploadFilePath.DATA_VIEW_PATH, num) + "scene.json";
@@ -738,6 +771,8 @@ public class BuildScenePostServiceImpl implements IBuildScenePostService {
         }else{
             sceneEditControls = sceneEditControlsService.getBySceneEditId(sceneEditInfo.getId());
             sceneEditInfoExt = sceneEditInfoExtService.getByEditInfoId(sceneEditInfo.getId());
+            sceneEditInfo.setVersion(sceneEditInfo.getVersion() + 1);
+            sceneEditInfoService.updateById(sceneEditInfo);
         }
         if(sceneEditControls == null){
             sceneEditControls = new SceneEditControls();
@@ -753,4 +788,117 @@ public class BuildScenePostServiceImpl implements IBuildScenePostService {
         }
         return new Object[]{sceneEditInfo, sceneEditInfoExt, sceneEditControls};
     }
+
+    public void uploadHouseTypeJson(String num) throws IOException {
+
+        JSONObject result = new JSONObject();
+        result.put("name", "houseType.json");
+        result.put("version", "2.1");
+
+        String floorplanCadPath = String.format(UploadFilePath.DATA_VIEW_PATH, num) + "floorplan_cad.json";
+        String floorcadStr = uploadToOssUtil.getObjectContent(this.bucket, floorplanCadPath);
+
+        JSONObject floorcadObj = JSON.parseObject(floorcadStr);
+        JSONArray floors = floorcadObj.getJSONArray("floors");
+
+        JSONArray targetFloors = new JSONArray();
+        result.put("floors", targetFloors);
+        for(int i = 0; i < floors.size(); i++){
+            JSONObject floor = (JSONObject)floors.get(i);
+            JSONArray[] pointsAndWalls = this.createHouseTypeJsonHandler(floor);
+            JSONArray points = pointsAndWalls[0];
+            JSONArray walls = pointsAndWalls[1];
+            JSONObject targetFloor = new JSONObject();
+            targetFloor.put("points", points);
+            targetFloor.put("walls", walls);
+            targetFloors.add(targetFloor);
+        }
+
+        String hourseTypeJsonPath = String.format(UploadFilePath.DATA_VIEW_PATH, num) + "houseType.json";
+        uploadToOssUtil.upload(result.toJSONString().getBytes(), hourseTypeJsonPath);
+
+        cn.hutool.core.io.FileUtil.writeString(result.toJSONString(), "F:\\test\\hourseType.json", StandardCharsets.UTF_8);
+    }
+
+    private JSONArray[] createHouseTypeJsonHandler(JSONObject floor){
+
+        JSONArray[] result = new JSONArray[2];
+
+        //处理点
+        Map<Integer, VertexBean> vertexMap = new HashMap<>();
+        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);
+
+            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());
+
+            vpMap.put(vertexId, pointId);
+        }
+
+        //处理墙
+        Map<Integer, SegmentBean> segmentMap = new HashMap<>();
+        Map<String, WallBean> wallMap = new HashMap<>();
+        Map<Integer, String> swMap = new HashMap<>();
+        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);
+        }
+
+        Collection<PointBean> pointBeans = pointMap.values();
+        for (PointBean pointBean : pointBeans) {
+            Map<String, String> parent = new HashMap<>();
+            String startParent = startMap.get(pointBean.getVectorId());
+            String endParent = endMap.get(pointBean.getVectorId());
+            parent.put(startParent, "start");
+            parent.put(endParent, "end");
+            pointBean.setParent(parent);
+        }
+        JSONArray pointArr = JSON.parseArray(JSON.toJSONString(pointBeans));
+        result[0] = pointArr;
+
+        Collection<WallBean> wallBeans = wallMap.values();
+        JSONArray wallArr = JSON.parseArray(JSON.toJSONString(wallBeans));
+        result[1] = wallArr;
+
+        return result;
+
+    }
+
+    public static void main(String[] args) {
+//        BuildScenePostServiceImpl.createHouseTypeJson();
+    }
+
 }

+ 238 - 4
4dkankan-center-scene/src/main/java/com/fdkankan/scene/service/impl/SceneEditInfoServiceImpl.java

@@ -8,6 +8,7 @@ import cn.hutool.core.util.ZipUtil;
 import com.alibaba.fastjson.JSON;
 import com.alibaba.fastjson.JSONArray;
 import com.alibaba.fastjson.JSONObject;
+import com.alibaba.fastjson.serializer.SerializerFeature;
 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
 import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
@@ -37,6 +38,7 @@ import com.fdkankan.redis.util.RedisLockUtil;
 import com.fdkankan.redis.util.RedisUtil;
 import com.fdkankan.scene.api.dto.SceneInfoDTO;
 import com.fdkankan.scene.bean.BoxPhotoBean;
+import com.fdkankan.scene.bean.RequestSceneProV4;
 import com.fdkankan.scene.bean.SceneJsonBean;
 import com.fdkankan.scene.bean.TagBean;
 import com.fdkankan.scene.callback.FdkkMiniReqErrorCallback;
@@ -48,6 +50,7 @@ import com.fdkankan.scene.entity.SceneEditInfoExt;
 import com.fdkankan.scene.entity.ScenePlus;
 import com.fdkankan.scene.entity.ScenePlusExt;
 import com.fdkankan.scene.entity.ScenePro;
+import com.fdkankan.scene.entity.SceneProV3;
 import com.fdkankan.scene.factory.FloorLogoHandlerFactory;
 import com.fdkankan.scene.factory.MusicHandlerFactory;
 import com.fdkankan.scene.factory.ScreenshotHandlerFactory;
@@ -80,6 +83,7 @@ import java.util.Set;
 import java.util.UUID;
 import java.util.stream.Collectors;
 import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.lang3.StringUtils;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.beans.factory.annotation.Value;
 import org.springframework.cloud.context.config.annotation.RefreshScope;
@@ -89,6 +93,7 @@ import java.io.IOException;
 import java.util.Calendar;
 import java.util.Objects;
 import org.springframework.transaction.annotation.Transactional;
+import org.springframework.util.ObjectUtils;
 import org.springframework.web.multipart.MultipartFile;
 
 /**
@@ -120,6 +125,12 @@ public class SceneEditInfoServiceImpl extends ServiceImpl<ISceneEditInfoMapper,
     private int waitTime;
     @Value("${http.host.4dkankanMini}")
     private String fkankanMiniHost;
+    @Value("${http.api-v4.getDataSyncByCameraId}")
+    private String URL_GET_DATASYNC_BY_CAMERAID;
+    @Value("${http.api-v4.getSceneProByNum}")
+    private String URL_GET_SCENEPRO_BY_NUM;
+    @Value("${http.api-v4.upgradeToV4ResultSync}")
+    private String URL_UPGRADE_TO_V4_RESULT_SYNC;
 
     @Autowired
     private ISceneEditControlsService sceneEditControlsService;
@@ -297,6 +308,14 @@ public class SceneEditInfoServiceImpl extends ServiceImpl<ISceneEditInfoMapper,
 //            sceneEditControlsService.updateById(sceneEditControls);
 //        }
 
+        // todo 调用v3接口同步场景缩略图url---------------------------------start
+        String url = fkankanMiniHost + URL_UPGRADE_TO_V4_RESULT_SYNC;
+        fdkankanMiniClient.upgradeToV4ResultSync(url,
+            RequestSceneProV4.builder().id(scenePlus.getId()).thumb(scenePlusExt.getThumb()).sceneName(sceneEditInfo.getTitle()).build(),
+            new FdkkMiniReqSuccessCallback(), new FdkkMiniReqErrorCallback()
+        );
+        // todo 调用v3接口同步场景缩略图url---------------------------------end
+
         return ResultData.ok();
     }
 
@@ -450,7 +469,7 @@ public class SceneEditInfoServiceImpl extends ServiceImpl<ISceneEditInfoMapper,
         if(Objects.isNull(cameraId)){
             return;
         }
-        String url = fkankanMiniHost + "/api/user/camera/getDataSyncByCameraId?cameraId=" + cameraId;
+        String url = fkankanMiniHost + URL_GET_DATASYNC_BY_CAMERAID + cameraId;
         Result<String> dataSyncResult = fdkankanMiniClient
             .getDataSyncType(url, new FdkkMiniReqSuccessCallback(), new FdkkMiniReqErrorCallback());
         sceneInfoVO.setDataSync(dataSyncResult.getMsg());
@@ -498,8 +517,32 @@ public class SceneEditInfoServiceImpl extends ServiceImpl<ISceneEditInfoMapper,
      **/
     private SceneInfoVO getSceneInfo4View(String num) throws Exception{
 
+        // TODO: 2022/5/19 请求v3的接口,获取场景的状态 待v3停机后要换成v4d的逻辑-------------------------start
+        String url = fkankanMiniHost + URL_GET_SCENEPRO_BY_NUM + num;
+        Result<SceneProV3> result = fdkankanMiniClient
+            .getSceneProByNum(url, new FdkkMiniReqSuccessCallback(),
+                new FdkkMiniReqErrorCallback());
+        SceneProV3 sceneProV3 = result.getData();
+        if(sceneProV3 == null || sceneProV3.getId() == null){
+            throw new BusinessException(ErrorCode.FAILURE_CODE_5005);
+        }
+        if(sceneProV3.getRecStatus().equals("I")){
+            throw new BusinessException(ErrorCode.FAILURE_CODE_5009);
+        }
+        if(SceneStatus.SUCCESS.code() != sceneProV3.getStatus()
+            && SceneStatus.NO_DISPLAY.code() != sceneProV3.getStatus()){
+            throw new BusinessException(ErrorCode.FAILURE_CODE_5033);
+        }
+        if(PayStatus.PAY.code() != sceneProV3.getPayStatus()){
+            throw new BusinessException(ErrorCode.FAILURE_CODE_5034);
+        }
+        // TODO: 2022/5/19 请求v3的接口,获取场景的状态 待v3停机后要换成v4d的逻辑-------------------------send
+
 //        ScenePro scenePro = sceneProService.findBySceneNum(num);
         ScenePlus scenePlus = scenePlusService.getScenePlusByNum(num);
+        if(Objects.isNull(scenePlus)){
+            throw new BusinessException(ErrorCode.FAILURE_CODE_5005);
+        }
 
         String key = String.format(RedisKey.SCENE_JSON, num);
         String sceneJson = redisUtil.get(key);
@@ -635,11 +678,27 @@ public class SceneEditInfoServiceImpl extends ServiceImpl<ISceneEditInfoMapper,
     @Override
     public ResultData resetCad(String num){
 
-        ScenePro scenePro = sceneProService.findBySceneNum(num);
         ScenePlus scenePlus = scenePlusService.getScenePlusByNum(num);
         if(Objects.isNull(scenePlus))
             throw new BusinessException(ErrorCode.FAILURE_CODE_5005);
+        ScenePlusExt scenePlusExt = scenePlusExtService
+            .getScenePlusExtByPlusId(scenePlus.getId());
+        String path = scenePlusExt.getDataSource();
 
+        //户型图上传
+        String  userEditPath = UploadFilePath.USER_EDIT_PATH + "floor-cad-%s.%s";
+        String floorCadPath = path + "/results/floorplan_cad";
+        List<String> floorCadList = FileUtil.getFileList(floorCadPath);
+        if(CollUtil.isNotEmpty(floorCadList)){
+            floorCadList.stream().forEach(str->{
+                String substring = str.substring(str.lastIndexOf(File.separator) + 1);
+                String[] arr = substring.split("floor");
+                String[] arr2 = arr[1].split("\\.");
+                uploadToOssUtil.upload(str, String.format(userEditPath, num, arr2[0], arr2[1]));
+            });
+        }
+
+        ScenePro scenePro = sceneProService.findBySceneNum(num);
         SceneEditInfo sceneEditInfoDb = this.getByScenePlusId(scenePlus.getId());
         SceneEditInfoExt sceneEditInfoExt = null;
         if(Objects.nonNull(sceneEditInfoDb)){
@@ -998,6 +1057,9 @@ public class SceneEditInfoServiceImpl extends ServiceImpl<ISceneEditInfoMapper,
             //如果是单张图片,直接提供oss url
             String localFilePath = localImagesPath + fileName;
             String ossFilePath = imgCachePath + fileName;
+            if(!cn.hutool.core.io.FileUtil.exist(localFilePath)){
+                throw new BusinessException(ErrorCode.FAILURE_CODE_5063);
+            }
             uploadToOssUtil.upload(localFilePath, ossFilePath);
             url = ossUrlPrefix + ossFilePath;
 //                FileUtils.downLoadFromUrl(imageUrl, fileName, localImagesPath);
@@ -1019,8 +1081,9 @@ public class SceneEditInfoServiceImpl extends ServiceImpl<ISceneEditInfoMapper,
 //                    }
 //                });
 //            }
-            if(!cn.hutool.core.io.FileUtil.exist(localImagesPath)){
-                throw new BusinessException(ErrorCode.FAILURE_CODE_7006);
+            if(!cn.hutool.core.io.FileUtil.exist(localImagesPath)
+                || cn.hutool.core.io.FileUtil.isDirEmpty(new File(localImagesPath))){
+                throw new BusinessException(ErrorCode.FAILURE_CODE_5063);
             }
 
             downloadName = num + "_images.zip";
@@ -1442,6 +1505,177 @@ public class SceneEditInfoServiceImpl extends ServiceImpl<ISceneEditInfoMapper,
         return ResultData.ok();
     }
 
+    @Override
+    public ResultData addMosaics(BaseDataParamVO param) throws Exception {
+
+        JSONArray mosaicArr = JSONArray.parseArray(param.getData());
+        if (CollUtil.isEmpty(mosaicArr) || mosaicArr.size() > 1) {
+            throw new BusinessException(ErrorCode.FAILURE_CODE_5012);
+        }
+        JSONObject mosicObj= mosaicArr.getJSONObject(0);
+
+        ScenePlus scenePlus = scenePlusService.getScenePlusByNum(param.getNum());
+        if(Objects.isNull(scenePlus)){
+            throw new BusinessException(ErrorCode.FAILURE_CODE_5005);
+        }
+        ScenePlusExt scenePlusExt = scenePlusExtService.getScenePlusExtByPlusId(scenePlus.getId());
+        SceneEditInfo sceneEditInfo = this.getByScenePlusId(scenePlus.getId());
+        SceneEditInfoExt sceneEditInfoExt = sceneEditInfoExtService.getByEditInfoId(sceneEditInfo.getId());
+
+        String dataViewPath = String.format(UploadFilePath.DATA_VIEW_PATH, param.getNum());
+        String imgViewPath = String.format(UploadFilePath.IMG_VIEW_PATH, param.getNum());
+
+        String path = scenePlusExt.getDataSource();
+        if(StrUtil.isNotEmpty(path) && path.startsWith("http")){
+            path = ConstantFilePath.BUILD_MODEL_PATH + File.separator + path.split("/")[path.split("/").length - 2];
+        }
+        String target = path + "_roi";
+
+        cn.hutool.core.io.FileUtil.del(target);
+
+        //文件上传的位置可以自定义
+        String filePath = target + File.separator + "extras" + File.separator + "images/";
+        File imageFile = new File(filePath);
+        if(!imageFile.getParentFile().exists()){
+            imageFile.getParentFile().mkdirs();
+        }
+        FileUtils.copyFolderAllFiles(path + "/caches/images/", filePath, true);
+
+        String mosaicData = sceneEditInfoExt.getMosaics();
+        JSONArray jsonArray = new JSONArray();
+        if(StrUtil.isNotEmpty(mosaicData)){
+            jsonArray = JSONArray.parseArray(mosaicData);
+        }
+        jsonArray.add(mosicObj);
+
+        // 准备算法数据
+        List<JSONObject> mosaicsList = new ArrayList<>();
+        for(int i = 0, len = jsonArray.size(); i < len; i++){
+            JSONObject jsonObject = jsonArray.getJSONObject(i);
+            boolean contains = false;
+            for (JSONObject item : mosaicsList) {
+                if(StringUtils.equals(item.getString("panoId"),jsonObject.getString("panoId"))){
+                    contains = true;
+                    item.getJSONArray("rect").addAll(jsonObject.getJSONArray("rect"));
+                }
+            }
+            if(!contains){
+                mosaicsList.add(jsonObject);
+            }
+        }
+        JSONObject roiImageJSon = new JSONObject();
+        roiImageJSon.put("batch",mosaicsList);
+
+        FileUtils.writeFile(target + File.separator + "extras" + File.separator + "image-ROI.json", JSON.toJSONString(roiImageJSon,SerializerFeature.DisableCircularReferenceDetect));
+
+        FileUtils.copyFile(path + File.separator + "results/vision.txt", target + File.separator+"extras/vision.txt", true);
+        FileUtils.copyFile(path + File.separator + "results/vision2.txt", target + File.separator+"extras/vision2.txt", true);
+        FileUtils.copyFile(path + File.separator + "data.json", target + File.separator+"data.json", true);
+        String data = FileUtils.readFile(target + File.separator+"data.json");
+        if(data != null){
+            JSONObject floorplanJson = new JSONObject();
+            floorplanJson.put("has_source_images", true);
+            floorplanJson.put("has_vision_txt", true);
+
+            JSONObject dataJson = JSONObject.parseObject(data);
+            dataJson.put("extras", floorplanJson);
+            //V5表示不需要生成high,low文件
+            dataJson.put("skybox_type", "SKYBOX_V6");
+            if(scenePlusExt.getSceneScheme() == 11){
+                dataJson.put("skybox_type", "SKYBOX_V7");
+            }
+            dataJson.put("split_type", "SPLIT_V18");
+            //sceneScheme为3切成瓦片图
+            if(scenePlusExt.getSceneScheme() == 3){
+                dataJson.put("skybox_type", "SKYBOX_V4");
+            }
+            FileUtils.writeFile(target + File.separator+"data.json", new String(dataJson.toString().getBytes(), "UTF-8"));
+        }
+
+        FileUtils.copyFile(path + File.separator + "project.json", target + File.separator+"project.json", true);
+
+        //进行计算
+        log.info("马赛克建模开始, num:{}, path:{}" + param.getNum(), target);
+        CreateObjUtil.build3dModel2(target , "1");
+        log.info("马赛克建模结束, num:{}, path:{}" + param.getNum(), target);
+
+        //读取upload文件,检验需要上传的文件是否存在
+        String uploadJsonPath = target + File.separator + "results" + File.separator + "upload.json";
+        boolean exist = ComputerUtil.checkComputeCompleted(uploadJsonPath, maxCheckTimes, waitTime);
+        if(!exist){
+            throw new BusinessException(ErrorCode.FAILURE_CODE_5042);
+        }
+        String uploadData = FileUtils.readFile(target + File.separator + "results" + File.separator + "upload.json");
+        JSONObject uploadJson = JSONObject.parseObject(uploadData);
+        JSONArray array = uploadJson.getJSONArray("upload");
+        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/", ""));
+            }
+            //low文件夹
+            if(fileJson.getIntValue("clazz") == 4){
+                map.put(target + File.separator + "results" +File.separator+ fileName,
+                    imgViewPath + "pan/low/"+ fileName.replace("low/", ""));
+            }
+
+            //tiles文件夹,亚马逊没有裁剪图片api,不需要上传4k图
+            if(fileJson.getIntValue("clazz") == 5){
+                map.put(target + File.separator + "results" + File.separator+ fileName,
+                    imgViewPath + fileName);
+            }
+
+            //tiles文件夹,亚马逊瓦片图
+            if(fileJson.getIntValue("clazz") == 7 ){
+                map.put(target + File.separator + "results" + File.separator+ fileName,
+                    imgViewPath + fileName);
+            }
+        }
+
+        for(String imagesName : imageFile.list()){
+            //覆盖原始图片资源
+            FileUtils.copyFile(target + File.separator + "extras/images/" + imagesName,
+                path + File.separator + "caches/images/" + imagesName, true);
+            FileUtils.deleteFile(target + File.separator + "extras/images/" + imagesName);
+        }
+
+        uploadToOssUtil.uploadMulFiles(map);
+
+        this.upgradeVersionById(sceneEditInfo.getId());
+
+        sceneEditInfoExt.setMosaics(JSON.toJSONString(jsonArray,SerializerFeature.DisableCircularReferenceDetect));
+        sceneEditInfoExtService.updateById(sceneEditInfoExt);
+
+        // 更新 scene.json
+        String sceneJsonPath = dataViewPath + "scene.json";
+        String sceneJson = uploadToOssUtil.getObjectContent(this.bucket, sceneJsonPath);
+        JSONObject scenejson = new JSONObject();
+        if(StrUtil.isNotEmpty(sceneJson)) {
+            scenejson = JSONObject.parseObject(sceneJson);
+        }
+        scenejson.put("mosaics",JSON.toJSONString(jsonArray, SerializerFeature.DisableCircularReferenceDetect));
+        Integer version = scenejson.getIntValue("version");
+        version = Objects.isNull(version) ? 1 : version + 1;
+        scenejson.put("version", version);
+        uploadToOssUtil.upload(scenejson.toJSONString().getBytes(), sceneJsonPath);
+
+        Map<String,Object> result = new HashMap<>(1);
+        result.put("mosaics",jsonArray);
+
+        return ResultData.ok(result);
+    }
+
     private void updateBoxVideos(SceneEditInfo sceneEditInfo, Long scenePlusId, String boxVideos){
         if(Objects.isNull(sceneEditInfo)){
             sceneEditInfo = new SceneEditInfo();

+ 57 - 36
4dkankan-center-scene/src/main/java/com/fdkankan/scene/service/impl/SceneEditServiceImpl.java

@@ -6,8 +6,10 @@ import cn.hutool.core.util.StrUtil;
 import com.alibaba.fastjson.JSON;
 import com.alibaba.fastjson.JSONArray;
 import com.alibaba.fastjson.JSONObject;
+import com.alibaba.fastjson.serializer.SerializerFeature;
 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.fdkankan.common.constant.CommonStatus;
+import com.fdkankan.common.constant.ConstantFilePath;
 import com.fdkankan.common.constant.ErrorCode;
 import com.fdkankan.common.constant.PayStatus;
 import com.fdkankan.common.constant.SceneStatus;
@@ -17,6 +19,7 @@ import com.fdkankan.common.exception.BusinessException;
 import com.fdkankan.common.response.Result;
 import com.fdkankan.common.response.ResultData;
 import com.fdkankan.common.util.DateExtUtil;
+import com.fdkankan.common.util.FileUtils;
 import com.fdkankan.fyun.oss.UploadToOssUtil;
 import com.fdkankan.platform.api.feign.PlatformGoodsClient;
 import com.fdkankan.platform.api.feign.PlatformUserClient;
@@ -25,6 +28,7 @@ import com.fdkankan.scene.bean.UserIncrementBean;
 import com.fdkankan.scene.callback.FdkkMiniReqErrorCallback;
 import com.fdkankan.scene.callback.FdkkMiniReqSuccessCallback;
 import com.fdkankan.scene.entity.ScenePlus;
+import com.fdkankan.scene.entity.SceneProV3;
 import com.fdkankan.scene.httpclient.FdkankanMiniClient;
 import com.fdkankan.scene.service.ISceneEditInfoExtService;
 import com.fdkankan.scene.service.ISceneEditInfoService;
@@ -37,16 +41,21 @@ import com.fdkankan.scene.vo.BaseSceneParamVO;
 import com.fdkankan.scene.vo.DeleteFileParamVO;
 import com.fdkankan.scene.vo.LocalesParamVO;
 import com.fdkankan.scene.vo.SceneAuthVO;
+import java.io.File;
 import java.io.IOException;
 import java.nio.charset.StandardCharsets;
 import java.util.ArrayList;
 import java.util.Date;
+import java.util.HashMap;
 import java.util.List;
+import java.util.Map;
 import java.util.Objects;
+import org.apache.commons.lang3.StringUtils;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.beans.factory.annotation.Value;
 import org.springframework.cloud.context.config.annotation.RefreshScope;
 import org.springframework.stereotype.Service;
+import org.springframework.util.ObjectUtils;
 
 /**
  * <p>
@@ -64,6 +73,8 @@ public class SceneEditServiceImpl implements ISceneEditService {
     private String bucket;
     @Value("${http.host.4dkankanMini}")
     private String fkankanMiniHost;
+    @Value("${http.api-v4.getSceneProByNum}")
+    private String URL_GET_SCENEPRO_BY_NUM;
     @Autowired
     ISceneProService sceneProService;
     @Autowired
@@ -82,17 +93,44 @@ public class SceneEditServiceImpl implements ISceneEditService {
     private ISceneEditInfoExtService sceneEditInfoExtService;
     @Autowired
     private FdkankanMiniClient fdkankanMiniClient;
+    @Value("${http.api.isLogin}")
+    private String URL_ISLOGIN;
 
     @Override
-    public SceneAuthVO getAuth(BaseSceneParamVO param) throws Exception{
+    public SceneAuthVO getAuth(String num, String token) throws Exception{
+
+        // TODO: 2022/5/19 请求v3的接口,获取场景的状态 待v3停机后要换成v4d的逻辑-------------------------start
+        String url = fkankanMiniHost + URL_GET_SCENEPRO_BY_NUM + num;
+        Result<SceneProV3> result = fdkankanMiniClient
+            .getSceneProByNum(url, new FdkkMiniReqSuccessCallback(),
+                new FdkkMiniReqErrorCallback());
+        SceneProV3 sceneProV3 = result.getData();
+        if(sceneProV3 == null || sceneProV3.getId() == null){
+            throw new BusinessException(ErrorCode.FAILURE_CODE_5005);
+        }
+        if(sceneProV3.getRecStatus().equals("I")){
+            throw new BusinessException(ErrorCode.FAILURE_CODE_5009);
+        }
+        if(SceneStatus.SUCCESS.code() != sceneProV3.getStatus()
+            && SceneStatus.NO_DISPLAY.code() != sceneProV3.getStatus()){
+            throw new BusinessException(ErrorCode.FAILURE_CODE_5033);
+        }
+        if(PayStatus.PAY.code() != sceneProV3.getPayStatus()){
+            throw new BusinessException(ErrorCode.FAILURE_CODE_5034);
+        }
+        // TODO: 2022/5/19 请求v3的接口,获取场景的状态 待v3停机后要换成v4d的逻辑-------------------------send
 
         ScenePlus scenePlus = scenePlusService.getOne(
-            new LambdaQueryWrapper<ScenePlus>().eq(ScenePlus::getNum, param.getNum())
-                .eq(ScenePlus::getPayStatus, PayStatus.PAY.code())
-                .in(ScenePlus::getSceneStatus, SceneStatus.SUCCESS.code(), SceneStatus.NO_DISPLAY.code()));
+            new LambdaQueryWrapper<ScenePlus>().eq(ScenePlus::getNum, num)
+                .eq(ScenePlus::getPayStatus, PayStatus.PAY.code()));
+//                .in(ScenePlus::getSceneStatus, SceneStatus.SUCCESS.code(), SceneStatus.NO_DISPLAY.code()));
         if(scenePlus == null){
             throw new BusinessException(ErrorCode.FAILURE_CODE_5005);
         }
+        if(scenePlus.getSceneStatus() == SceneStatus.FAILD.code()
+            || scenePlus.getSceneStatus() == SceneStatus.wait.code()){
+            throw new BusinessException(ErrorCode.FAILURE_CODE_5033);
+        }
         //判断该场景是否属于增值权益
         boolean isVip = false;
         //获取该相机是否有权益
@@ -130,40 +168,22 @@ public class SceneEditServiceImpl implements ISceneEditService {
 //            }
 //        }
         // TODO: 2022/4/25 v3v4共存过渡期结束需要删除,恢复上面注释内容 ------------------------------------------start
-        String url = fkankanMiniHost + "/api/user/increment/findByCameraId?cameraId=" + scenePlus.getCameraId();
-        Result<UserIncrementBean> userIncrementResult =
-            fdkankanMiniClient.getUserIncrementByCameraId(
-                url, new FdkkMiniReqSuccessCallback(), new FdkkMiniReqErrorCallback());
-        UserIncrementBean userIncrement = userIncrementResult.getData();
-        if(userIncrement != null){
-            if(userIncrement.getIsExpired() == 0){
-                isVip = true;
-            }
-            if(userIncrement.getIsExpired() == 1){
-                isExpired  = true;
-            }
-        }else{
-            url = fkankanMiniHost + "/api/user/camera/getCameraByCameraId?cameraId=" + scenePlus.getCameraId();
-            Result<CameraBean> cameraResult =
-                fdkankanMiniClient.getCameraByCameraId(
-                    url,new FdkkMiniReqSuccessCallback(), new FdkkMiniReqErrorCallback());
-            CameraBean camera = cameraResult.getData();
-            if(camera == null || Objects.isNull(camera.getId())){
-                throw new BusinessException(ServerCode.FEIGN_REQUEST_FAILD);
-            }
-            Date date = DateUtil.parse("2021-09-09 00:00:00", DateExtUtil.dateStyle);
-            //非07批次的放开
-            String pc = camera.getSnCode().substring(0,2);
-            if(!pc.equals("07") ){
-                if(camera.getCreateTime()!=null && date.after(camera.getCreateTime())){
-                    isVip = true;
-                    isExpired  = false;
-                }
-            }
-        }
+        url = fkankanMiniHost + URL_ISLOGIN + num;
+        Result<Map<String, Object>> isLoginResult = fdkankanMiniClient
+            .getIsLogin(url, token, new FdkkMiniReqSuccessCallback(),
+                new FdkkMiniReqErrorCallback());
+        Map<String, Object> data = isLoginResult.getData();
+        isVip = (boolean)data.get("isIncrement");
+        isExpired = (boolean)data.get("isExpired");
+        Integer company = data.get("company") == null ? null : (int)data.get("company");
         // TODO: 2022/4/25 v3v4共存过渡期结束需要删除,恢复上面注释内容 ------------------------------------------end
 
-        return SceneAuthVO.builder().isExpired(isExpired).isVip(isVip).build();
+        return SceneAuthVO.builder()
+            .isExpired(isExpired).isVip(isVip)
+            .company(company)
+            .exclude(data.get("exclude"))
+            .include(data.get("include"))
+            .build();
     }
 
     @Override
@@ -233,4 +253,5 @@ public class SceneEditServiceImpl implements ISceneEditService {
 
         return ResultData.ok();
     }
+
 }

+ 10 - 10
4dkankan-center-scene/src/main/java/com/fdkankan/scene/service/impl/SceneProServiceImpl.java

@@ -31,8 +31,12 @@ import com.fdkankan.redis.constant.RedisLockKey;
 import com.fdkankan.redis.util.RedisLockUtil;
 import com.fdkankan.redis.util.RedisUtil;
 import com.fdkankan.scene.bean.IconBean;
+import com.fdkankan.scene.bean.RequestSceneProV4;
 import com.fdkankan.scene.bean.TagBean;
+import com.fdkankan.scene.callback.FdkkMiniReqErrorCallback;
+import com.fdkankan.scene.callback.FdkkMiniReqSuccessCallback;
 import com.fdkankan.scene.entity.*;
+import com.fdkankan.scene.httpclient.FdkankanMiniClient;
 import com.fdkankan.scene.mapper.ISceneProMapper;
 import com.fdkankan.scene.service.*;
 import com.fdkankan.scene.vo.*;
@@ -75,36 +79,30 @@ public class SceneProServiceImpl extends ServiceImpl<ISceneProMapper, ScenePro>
 
     @Value("${oss.prefix.ali}")
     private String prefixAli;
-
     @Value("${oss.prefix.url}")
     private String ossUrlPrefix;
-
     @Value("${upload.type}")
     private String type;
-
     @Value("${hot.domain.list}")
     private String hotDomainList;
-
     @Value("${hot.delete}")
     private String hotDelete;
-
     @Value("${main.url}")
     private String mainUrl;
-
     @Value("${scene.url}")
     private String sceneUrl;
-
     @Value("${scene.pro.url}")
     private String sceneProUrl;
-
     @Value("${scene.pro.new.url}")
     private String sceneProNewUrl;
-
     @Value("${ecs.checkFile.maxTimes:5}")
     private int maxCheckTimes;
-
     @Value("${ecs.checkFile.waitTime:5000}")
     private int waitTime;
+    @Value("${http.host.4dkankanMini}")
+    private String fkankanMiniHost;
+    @Value("${http.api-v4.upgradeToV4ResultSync}")
+    private String URL_UPGRADE_TO_V4_RESULT_SYNC;
 
     @Autowired
     @Qualifier("uploadToOssUtil")
@@ -143,6 +141,8 @@ public class SceneProServiceImpl extends ServiceImpl<ISceneProMapper, ScenePro>
     IFdkkLaserService fdkkLaserService;
     @Resource
     ISceneProMapper sceneProMapper;
+    @Autowired
+    private FdkankanMiniClient fdkankanMiniClient;
 
     @Override
     public List<SceneVO> convert(List<ScenePro> list){

+ 47 - 5
4dkankan-center-scene/src/main/java/com/fdkankan/scene/service/impl/SceneUpgradeToV4Service.java

@@ -4,14 +4,17 @@ import cn.hutool.core.util.StrUtil;
 import com.alibaba.fastjson.JSON;
 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
+import com.fdkankan.common.constant.ConstantFilePath;
 import com.fdkankan.common.constant.ErrorCode;
 import com.fdkankan.common.response.ResultData;
+import com.fdkankan.fyun.oss.UploadToOssUtil;
 import com.fdkankan.rabbitmq.util.RabbitMqProducer;
 import com.fdkankan.redis.constant.RedisKey;
 import com.fdkankan.redis.constant.RedisLockKey;
 import com.fdkankan.redis.util.RedisLockUtil;
 import com.fdkankan.redis.util.RedisUtil;
 import com.fdkankan.scene.bean.SceneUpgradeProgressBean;
+import com.fdkankan.scene.entity.ScenePlus;
 import com.fdkankan.scene.entity.ScenePlusExt;
 import com.fdkankan.scene.entity.SceneProEdit;
 import com.fdkankan.scene.entity.SceneProEditExt;
@@ -30,6 +33,7 @@ import com.fdkankan.scene.service.ISceneProService;
 import com.fdkankan.scene.service.ISceneProV3Service;
 import com.fdkankan.scene.service.ISceneRepairLogService;
 import com.fdkankan.scene.service.ISceneUpgradeToV4Service;
+import com.fdkankan.scene.vo.SceneInfoVO;
 import com.fdkankan.scene.vo.UpgradeToV4ParamVO;
 import java.util.HashMap;
 import java.util.Map;
@@ -53,6 +57,8 @@ public class SceneUpgradeToV4Service implements ISceneUpgradeToV4Service {
 
     @Value("${queue.scene.upgrade-to-v4}")
     private String upgradeToV4;
+    @Value("${oss.bucket:4dkankan}")
+    private String bucket;
 
     @Autowired
     private ISceneProV3Service sceneProV3Service;
@@ -80,8 +86,8 @@ public class SceneUpgradeToV4Service implements ISceneUpgradeToV4Service {
     private ISceneProEditService sceneProEditService;
     @Autowired
     private ISceneProEditExtService sceneProEditExtService;
-
-
+    @Autowired
+    private UploadToOssUtil uploadToOssUtil;
 
     @Override
     public ResultData upgradeToV4(UpgradeToV4ParamVO param) {
@@ -106,9 +112,11 @@ public class SceneUpgradeToV4Service implements ISceneUpgradeToV4Service {
                     redisLockUtil.unlockLua(lockKey);
                     return ResultData.error(ErrorCode.FAILURE_CODE_7019);
                 }
-                if(sceneRepairLog.getState() == 1){
-                    redisLockUtil.unlockLua(lockKey);
-                    return ResultData.error(ErrorCode.FAILURE_CODE_7020);
+                if(!param.isReUpgrade()){
+                    if(sceneRepairLog.getState() == 1){
+                        redisLockUtil.unlockLua(lockKey);
+                        return ResultData.error(ErrorCode.FAILURE_CODE_7020);
+                    }
                 }
             }
 
@@ -167,4 +175,38 @@ public class SceneUpgradeToV4Service implements ISceneUpgradeToV4Service {
         return ResultData.ok(progressBean);
     }
 
+    @Override
+    public ResultData getSceneViewInfo(String num) {
+        ScenePlus scenePlus = scenePlusService.getScenePlusByNum(num);
+        String key = String.format(RedisKey.SCENE_JSON, num);
+        String sceneJson = redisUtil.get(key);
+        SceneInfoVO sceneInfoVO = null;
+        //先查询redis
+        if(StrUtil.isNotEmpty(sceneJson)) {
+            sceneInfoVO = JSON.parseObject(sceneJson, SceneInfoVO.class);
+            sceneInfoVO.setScenePassword(null);
+            if(Objects.isNull(sceneInfoVO.getFloorPlanAngle())){
+                sceneInfoVO.setFloorPlanAngle(0f);
+            }
+            if(Objects.isNull(sceneInfoVO.getFloorPlanCompass())){
+                sceneInfoVO.setFloorPlanCompass(0f);
+            }
+            return ResultData.ok(sceneInfoVO);
+        }
+
+        //如果redis没找到,从scene.json中获取
+        String objectName = String.format(ConstantFilePath.SCENE_VIEW_DATA_DATA_SCENEJSON, num);
+        String objectContent = uploadToOssUtil.getObjectContent(bucket, objectName);
+        if(StrUtil.isEmpty(objectContent))
+            return ResultData.ok();
+        sceneInfoVO = JSON.parseObject(objectContent, SceneInfoVO.class);
+        sceneInfoVO.setScenePassword(null);
+        if(Objects.isNull(sceneInfoVO.getFloorPlanAngle())){
+            sceneInfoVO.setFloorPlanAngle(0f);
+        }
+        if(Objects.isNull(sceneInfoVO.getFloorPlanCompass())){
+            sceneInfoVO.setFloorPlanCompass(0f);
+        }
+        return ResultData.ok(sceneInfoVO);
+    }
 }

+ 32 - 4
4dkankan-center-scene/src/main/java/com/fdkankan/scene/service/impl/SceneUploadServiceImpl.java

@@ -22,7 +22,10 @@ import com.fdkankan.scene.mapper.ISceneUploadMapper;
 import com.fdkankan.scene.service.ISceneProService;
 import com.fdkankan.scene.service.ISceneUploadService;
 import com.fdkankan.scene.vo.DeleteFileParamVO;
+import com.fdkankan.scene.vo.UploadContentParamVO;
 import java.io.IOException;
+import java.nio.charset.Charset;
+import java.nio.charset.StandardCharsets;
 import java.util.HashSet;
 import java.util.Set;
 import org.apache.commons.lang3.StringUtils;
@@ -63,11 +66,15 @@ public class SceneUploadServiceImpl extends ServiceImpl<ISceneUploadMapper, Scen
     @Value("${oss.bucket:4dkankan}")
     private String bucket;
 
+    @Value("${oss.prefix.url}")
+    private String ossUrlPrefix;
+
     @Autowired
     private SSOLoginHelper ssoLoginHelper;
 
     @Override
-    public String uploads(String imgData,String fileName,String blzType,MultipartFile[] files,String sceneCode,Integer type,String token) throws Exception{
+    public String uploads(String imgData,String fileName,String blzType,MultipartFile[] files,
+        String sceneCode,Integer type,String token, String uploadPath) throws Exception{
         SSOUser ssoUser = ssoLoginHelper.loginCheck(token);
         Long userId = ssoUser == null ? null :ssoUser.getId();
 
@@ -79,7 +86,7 @@ public class SceneUploadServiceImpl extends ServiceImpl<ISceneUploadMapper, Scen
         if(files !=null && files.length >0){
             multipartFiles.addAll(Arrays.asList(files));
         }
-        return this.uploadFiles(fileName,blzType,multipartFiles,sceneCode,type,userId);
+        return this.uploadFiles(fileName,blzType,multipartFiles,sceneCode,type,userId,uploadPath);
     }
 
     @Override
@@ -107,7 +114,8 @@ public class SceneUploadServiceImpl extends ServiceImpl<ISceneUploadMapper, Scen
         return ResultData.ok();
     }
 
-    public String uploadFiles(String sendFileName,String bizType,List<MultipartFile> files, String sceneCode, Integer type,Long userId) throws Exception{
+    public String uploadFiles(String sendFileName,String bizType,List<MultipartFile> files,
+        String sceneCode, Integer type,Long userId, String uploadPath) throws Exception{
         if (StrUtil.isEmpty(sceneCode))
             throw new BusinessException(ServerCode.PARAM_REQUIRED, "num");
         if(CollUtil.isEmpty(files))
@@ -129,7 +137,7 @@ public class SceneUploadServiceImpl extends ServiceImpl<ISceneUploadMapper, Scen
             if(files.size() ==1 && StringUtils.isNotBlank(sendFileName)){
                 realFileName = sendFileName ;
             }
-            String ossPath = String.format(UploadFilePath.USER_EDIT_PATH ,sceneCode) + realFileName;
+            String ossPath = StrUtil.isNotBlank(uploadPath) ? uploadPath : (String.format(UploadFilePath.USER_EDIT_PATH ,sceneCode) + realFileName);
             try {
                 uploadToOssUtil.upload2(newFile.getPath(),ossPath);
             }catch (Exception e){
@@ -186,4 +194,24 @@ public class SceneUploadServiceImpl extends ServiceImpl<ISceneUploadMapper, Scen
         this.save(sceneUpload);
     }
 
+    @Override
+    public String uploadContent(UploadContentParamVO param) throws Exception {
+
+        String ossPath = param.getOssPath();
+        String fileName = ossPath.substring(ossPath.lastIndexOf("/") + 1);
+        if(StrUtil.isEmpty(fileName)){
+            throw new BusinessException(ErrorCode.FAILURE_CODE_7012);
+        }
+        String suffix = fileName.substring(fileName.lastIndexOf("."));
+        if(StrUtil.isEmpty(suffix)){
+            throw new BusinessException(ErrorCode.FAILURE_CODE_7012);
+        }
+
+        File tempFile = File.createTempFile(UUID.randomUUID().toString(), suffix);
+        cn.hutool.core.io.FileUtil.writeString(param.getContent(), tempFile, StandardCharsets.UTF_8);
+        uploadToOssUtil.upload(tempFile.getPath(), param.getOssPath());
+        tempFile.deleteOnExit();
+
+        return this.ossUrlPrefix + param.getOssPath();
+    }
 }

+ 7 - 0
4dkankan-center-scene/src/main/java/com/fdkankan/scene/vo/SceneAuthVO.java

@@ -1,6 +1,7 @@
 package com.fdkankan.scene.vo;
 
 import com.alibaba.fastjson.annotation.JSONField;
+import java.util.List;
 import lombok.AllArgsConstructor;
 import lombok.Builder;
 import lombok.Data;
@@ -34,6 +35,12 @@ public class SceneAuthVO {
      */
     private boolean isVip;
 
+    private Integer company;
+
+    private Object exclude;
+
+    private Object include;
+
     public void setIsExpired(boolean isExpired){
         this.isExpired = isExpired;
     }

+ 5 - 0
4dkankan-center-scene/src/main/java/com/fdkankan/scene/vo/SceneInfoVO.java

@@ -166,6 +166,11 @@ public class SceneInfoVO {
      */
     private Integer tours;
 
+    /**
+     * 马赛克数据
+     */
+    private String mosaics;
+
 
 
 

+ 2 - 0
4dkankan-center-scene/src/main/java/com/fdkankan/scene/vo/UpgradeToV4ParamVO.java

@@ -14,6 +14,8 @@ import lombok.Data;
 @Data
 public class UpgradeToV4ParamVO {
 
+    private boolean reUpgrade;
+
     @NotEmpty(message = "scenePro不能为空")
     private String scenePro;
 

+ 23 - 0
4dkankan-center-scene/src/main/java/com/fdkankan/scene/vo/UploadContentParamVO.java

@@ -0,0 +1,23 @@
+package com.fdkankan.scene.vo;
+
+import javax.validation.constraints.NotBlank;
+import lombok.Data;
+
+/**
+ * <p>
+ * TODO
+ * </p>
+ *
+ * @author dengsixing
+ * @since 2022/6/8
+ **/
+@Data
+public class UploadContentParamVO {
+
+    @NotBlank(message = "content不能为空")
+    private String content;
+
+    @NotBlank(message = "ossPath不能为空")
+    private String ossPath;
+
+}

+ 1 - 1
4dkankan-center-scene/src/main/resources/bootstrap-test.yml

@@ -16,7 +16,7 @@ spring:
             group: DEFAULT_GROUP
             refresh: true
 
-          - data-id: common-redis-config.yaml
+          - data-id: common-redis-config-52.yaml
             group: DEFAULT_GROUP
             refresh: true
 

+ 29 - 0
4dkankan-common/src/main/java/com/fdkankan/common/model/SSOUser.java

@@ -0,0 +1,29 @@
+package com.fdkankan.common.model;
+
+import java.io.Serializable;
+import java.util.Set;
+import lombok.Data;
+
+/**
+ * sso user
+ *
+ *  2018-04-02 19:59:49
+ */
+@Data
+public class SSOUser implements Serializable {
+
+    private static final long serialVersionUID = -2560069033053679931L;
+
+    private Long id;
+
+    private String userName;
+
+    private String password;
+
+    private String email;
+
+    private Set<String> permissionSet;
+
+    private Set<String> roleSet;
+
+}

+ 12 - 0
4dkankan-common/src/main/java/com/fdkankan/common/user/SSOLoginHelper.java

@@ -7,8 +7,10 @@ import org.springframework.stereotype.Component;
 
 @Component
 public class SSOLoginHelper {
+
     @Autowired
     private SSOLoginStore ssoLoginStore;
+
     public  SSOUser loginCheck(String token) {
         if (token != null && token.trim().length() > 0) {
             String username = JwtUtil.getUsername(token);
@@ -20,6 +22,16 @@ public class SSOLoginHelper {
         return null;
     }
 
+    public com.fdkankan.common.model.SSOUser loginCheckV3(String token) {
+        if (token != null && token.trim().length() > 0) {
+            com.fdkankan.common.model.SSOUser ssoUser = ssoLoginStore.getV3(token);
+            if (ssoUser != null) {
+                return ssoUser;
+            }
+        }
+        return null;
+    }
+
     public String login(String loginType,String userName) {
         return this.login(loginType,userName,null, null);
     }

+ 25 - 0
4dkankan-common/src/main/java/com/fdkankan/common/user/SSOLoginStore.java

@@ -1,13 +1,23 @@
 package com.fdkankan.common.user;
 
+import cn.hutool.core.util.ObjectUtil;
 import com.alibaba.fastjson.JSONObject;
 import com.fdkankan.common.constant.LoginType;
 import com.fdkankan.redis.constant.RedisKey;
 import com.fdkankan.redis.util.RedisUtil;
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.nio.charset.StandardCharsets;
+import java.util.Objects;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Qualifier;
+import org.springframework.data.redis.core.RedisTemplate;
 import org.springframework.stereotype.Component;
 
 import javax.annotation.Resource;
 
+@Slf4j
 @Component
 public class SSOLoginStore {
 
@@ -27,6 +37,20 @@ public class SSOLoginStore {
         return null;
     }
 
+
+    @Resource
+    @Qualifier("redisTemplate2")
+    private RedisTemplate redisTemplate2;
+
+    public  com.fdkankan.common.model.SSOUser getV3(String token) {
+        String redisKey = "token#".concat(token);
+        Object obj = redisTemplate2.opsForValue().get(redisKey);
+        if(Objects.nonNull(obj)){
+            return (com.fdkankan.common.model.SSOUser)obj;
+        }
+        return null;
+    }
+
     /**
      * remove
      * @param loginType     登录类型
@@ -74,4 +98,5 @@ public class SSOLoginStore {
         return String.format(RedisKey.SSO_USER,userName);
     }
 
+
 }

+ 38 - 0
4dkankan-common/src/main/java/com/fdkankan/common/util/WebUtil.java

@@ -0,0 +1,38 @@
+package com.fdkankan.common.util;
+
+import cn.hutool.http.ContentType;
+import com.alibaba.fastjson.JSON;
+import java.util.HashMap;
+import java.util.Map;
+import javax.servlet.http.HttpServletRequest;
+import org.aspectj.lang.JoinPoint;
+import org.aspectj.lang.reflect.MethodSignature;
+import org.springframework.web.multipart.MultipartFile;
+
+/**
+ * <p>
+ * TODO
+ * </p>
+ *
+ * @author dengsixing
+ * @since 2022/6/9
+ **/
+public class WebUtil {
+
+    /**
+     * 获取请求参数中的场景码
+     * @param pjp
+     * @param request
+     * @return
+     */
+    public static String getNum(JoinPoint pjp, HttpServletRequest request){
+        Object[] args = pjp.getArgs();
+        String contentType = request.getContentType();
+        if(contentType.contains(ContentType.JSON.getValue())){
+            HashMap hashMap = JSON.parseObject(JSON.toJSONString(args[0]), HashMap.class);
+            return (String) hashMap.get("num");
+        }
+        return request.getParameter("num");
+    }
+
+}

BIN
document/git分支管理说明.docx