Przeglądaj źródła

Merge branch 'release' into feature-local-20221110

dengsixing 2 lat temu
rodzic
commit
5be9936d18
25 zmienionych plików z 623 dodań i 94 usunięć
  1. 6 0
      pom.xml
  2. 27 0
      src/main/java/com/fdkankan/scene/bean/BoxModelBean.java
  3. 11 0
      src/main/java/com/fdkankan/scene/bean/SceneJsonBean.java
  4. 5 5
      src/main/java/com/fdkankan/scene/config/InterceptorConfig.java
  5. 3 3
      src/main/java/com/fdkankan/scene/controller/SceneController.java
  6. 67 1
      src/main/java/com/fdkankan/scene/controller/SceneEditController.java
  7. 15 0
      src/main/java/com/fdkankan/scene/controller/TestController.java
  8. 12 0
      src/main/java/com/fdkankan/scene/entity/SceneEditInfo.java
  9. 6 0
      src/main/java/com/fdkankan/scene/entity/SceneEditInfoExt.java
  10. 19 0
      src/main/java/com/fdkankan/scene/listener/RabbitMqListener.java
  11. 24 0
      src/main/java/com/fdkankan/scene/service/IBoxModelService.java
  12. 4 1
      src/main/java/com/fdkankan/scene/service/IScenePlusService.java
  13. 2 0
      src/main/java/com/fdkankan/scene/service/ISceneProService.java
  14. 1 1
      src/main/java/com/fdkankan/scene/service/ISurveillanceService.java
  15. 245 0
      src/main/java/com/fdkankan/scene/service/impl/BoxModelServiceImpl.java
  16. 29 18
      src/main/java/com/fdkankan/scene/service/impl/SceneEditInfoServiceImpl.java
  17. 83 5
      src/main/java/com/fdkankan/scene/service/impl/ScenePlusServiceImpl.java
  18. 6 0
      src/main/java/com/fdkankan/scene/service/impl/SceneProServiceImpl.java
  19. 3 3
      src/main/java/com/fdkankan/scene/service/impl/SurveillanceServiceImpl.java
  20. 25 0
      src/main/java/com/fdkankan/scene/vo/BaseJsonDataParamVO.java
  21. 3 1
      src/main/java/com/fdkankan/scene/vo/SceneDataDownloadVO.java
  22. 5 0
      src/main/java/com/fdkankan/scene/vo/SceneEditInfoParamVO.java
  23. 11 0
      src/main/java/com/fdkankan/scene/vo/SceneInfoVO.java
  24. 10 55
      src/main/resources/bootstrap-test-eur.yml
  25. 1 1
      src/main/resources/bootstrap-test.yml

+ 6 - 0
pom.xml

@@ -99,6 +99,12 @@
         </dependency>
 
         <dependency>
+            <groupId>com.fdkankan</groupId>
+            <artifactId>4dkankan-utils-image</artifactId>
+            <version>3.0.0-SNAPSHOT</version>
+        </dependency>
+
+        <dependency>
             <groupId>org.springframework.boot</groupId>
             <artifactId>spring-boot-starter-test</artifactId>
             <scope>test</scope>

+ 27 - 0
src/main/java/com/fdkankan/scene/bean/BoxModelBean.java

@@ -0,0 +1,27 @@
+package com.fdkankan.scene.bean;
+
+import com.alibaba.fastjson.JSONObject;
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+/**
+ * <p>
+ * TODO
+ * </p>
+ *
+ * @author dengsixing
+ * @since 2022/5/10
+ **/
+@Data
+@Builder
+@NoArgsConstructor
+@AllArgsConstructor
+public class BoxModelBean {
+
+    private Long createTime;
+
+    private JSONObject boxModel;
+
+}

+ 11 - 0
src/main/java/com/fdkankan/scene/bean/SceneJsonBean.java

@@ -1,5 +1,6 @@
 package com.fdkankan.scene.bean;
 
+import com.alibaba.fastjson.JSONArray;
 import com.alibaba.fastjson.JSONObject;
 import com.fdkankan.scene.vo.SceneEditControlsVO;
 import lombok.AllArgsConstructor;
@@ -132,6 +133,11 @@ public class SceneJsonBean {
     private String boxPhotos;
 
     /**
+     * 空间模型数据
+     */
+    private String boxModels;
+
+    /**
      *点位视频
      */
     private String videos;
@@ -164,6 +170,11 @@ public class SceneJsonBean {
     private Float floorPlanCompass;
 
     /**
+     * 用户上传自定义平面图
+     */
+    private JSONArray floorPlanUpload;
+
+    /**
      * 是否保存导览
      */
     private Integer tours;

+ 5 - 5
src/main/java/com/fdkankan/scene/config/InterceptorConfig.java

@@ -15,11 +15,11 @@ public class InterceptorConfig implements WebMvcConfigurer {
 	@Autowired
 	private TokenInterceptor tokenInterceptor;
 
-	@Override
-	public void addCorsMappings(CorsRegistry registry) {
-		registry.addMapping("/**").allowCredentials(true).allowedHeaders("*").allowedOrigins("*").allowedMethods("*");
-
-	}
+//	@Override
+//	public void addCorsMappings(CorsRegistry registry) {
+//		registry.addMapping("/**").allowCredentials(true).allowedHeaders("*").allowedOrigins("*").allowedMethods("*");
+//
+//	}
 
 	@Override
 	public void addInterceptors(InterceptorRegistry registry) {

+ 3 - 3
src/main/java/com/fdkankan/scene/controller/SceneController.java

@@ -73,9 +73,9 @@ public class SceneController extends BaseController {
      * @param param
      * @return com.fdkankan.web.response.ResultData
      **/
-    @PostMapping(value = "/downLoadZSData")
-    public ResultData downLoadZSData(@Validated BaseSceneParamVO param) throws Exception{
-        return scenePlusService.downLoadZSData(param);
+    @GetMapping(value = "/downLoadZSData")
+    public ResultData downLoadZSData(String sceneNum) throws Exception{
+        return scenePlusService.downLoadZSData(sceneNum);
     }
 
 }

+ 67 - 1
src/main/java/com/fdkankan/scene/controller/SceneEditController.java

@@ -5,15 +5,18 @@ import com.fdkankan.common.constant.SceneInfoReqType;
 import com.fdkankan.common.exception.BusinessException;
 import com.fdkankan.model.utils.CreateHouseJsonUtil;
 import com.fdkankan.scene.annotation.CheckPermit;
+import com.fdkankan.scene.service.IBoxModelService;
 import com.fdkankan.scene.service.IDownloadTourVideoService;
 import com.fdkankan.scene.service.ISceneEditInfoService;
 import com.fdkankan.scene.service.ISceneEditService;
+import com.fdkankan.scene.service.IScenePlusService;
 import com.fdkankan.scene.service.ISceneProService;
 import com.fdkankan.scene.service.ISceneUploadService;
 import com.fdkankan.scene.service.ISurveillanceService;
 import com.fdkankan.scene.vo.BallScreenVideoParamVO;
 import com.fdkankan.scene.vo.BaseDataParamVO;
 import com.fdkankan.scene.vo.BaseFileParamVO;
+import com.fdkankan.scene.vo.BaseJsonDataParamVO;
 import com.fdkankan.scene.vo.BaseSceneParamVO;
 import com.fdkankan.scene.vo.BaseSidParamVO;
 import com.fdkankan.scene.vo.DeleteFileParamVO;
@@ -77,7 +80,10 @@ public class SceneEditController extends BaseController {
     private IDownloadTourVideoService downloadTourVideoService;
     @Autowired
     private ISurveillanceService surveillanceService;
-
+    @Autowired
+    private IBoxModelService boxModelService;
+    @Autowired
+    private IScenePlusService scenePlusService;
 
     /**
      * <p>
@@ -792,4 +798,64 @@ public class SceneEditController extends BaseController {
         return ResultData.ok(surveillanceService.listSurveillance(param.getNum()));
     }
 
+    /**
+     * <p>
+     上传空间模型
+     * </p>
+     * @author dengsixing
+     * @date 2022/10/19
+     * @param num
+     * @param sid
+     * @param file
+     * @return com.fdkankan.common.response.ResultData
+     **/
+    @CheckPermit
+    @PostMapping("/model/box/upload")
+    public ResultData uploadBoxModel(
+        @RequestParam(value = "num") String num,
+        @RequestParam(value = "sid") String sid,
+        @RequestParam(value = "file") MultipartFile file) throws Exception {
+        return boxModelService.uploadBoxModel(num, sid, file);
+    }
+
+    /**
+     * <p>
+     保存空间模型
+     * </p>
+     * @author dengsixing
+     * @date 2022/10/19
+     * @param param
+     * @return com.fdkankan.common.response.ResultData
+     **/
+    @CheckPermit
+    @PostMapping("/model/box/save")
+    public ResultData saveBoxModel(@RequestBody @Validated BaseJsonDataParamVO param) throws Exception {
+        return boxModelService.saveBoxModel(param);
+    }
+
+    /**
+     * <p>
+     删除空间模型
+     * </p>
+     * @author dengsixing
+     * @date 2022/10/19
+     * @param param
+     * @return com.fdkankan.common.response.ResultData
+     **/
+    @CheckPermit
+    @PostMapping("/model/box/delete")
+    public ResultData delBoxModel(@RequestBody @Validated DeleteSidParamVO param) throws Exception {
+        return boxModelService.deleteBoxModel(param);
+    }
+
+    /**
+     * 上传二维码和分享的logo
+     * @return
+     */
+    @PostMapping(value = "/uploadShareLogo")
+    public ResultData uploadShareLogo(@RequestParam("num") String num, @RequestParam("file") MultipartFile file) throws Exception {
+        return scenePlusService.uploadShareLogo(num, file);
+    }
+
+
 }

+ 15 - 0
src/main/java/com/fdkankan/scene/controller/TestController.java

@@ -1,5 +1,9 @@
 package com.fdkankan.scene.controller;
 
+import com.fdkankan.rabbitmq.util.RabbitMqProducer;
+import com.fdkankan.web.response.ResultData;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.GetMapping;
 import org.springframework.web.bind.annotation.RequestMapping;
 import org.springframework.web.bind.annotation.RestController;
 
@@ -15,4 +19,15 @@ import org.springframework.web.bind.annotation.RestController;
 @RequestMapping("/test")
 public class TestController {
 
+    @Autowired
+    private RabbitMqProducer rabbitMqProducer;
+
+    @GetMapping("/test")
+    public ResultData test(){
+        for (int i = 0; i < 100; i++){
+            rabbitMqProducer.sendByWorkQueue("test_dsx", "{\"name\":123}");
+        }
+        return ResultData.ok();
+    }
+
 }

+ 12 - 0
src/main/java/com/fdkankan/scene/entity/SceneEditInfo.java

@@ -149,6 +149,12 @@ public class SceneEditInfo implements Serializable {
     private String boxPhotos;
 
     /**
+     * 空间模型数据
+     */
+    @TableField("box_models")
+    private String boxModels;
+
+    /**
      * 是否需要处理球幕视频
      */
     @TableField("build_video_status")
@@ -173,6 +179,12 @@ public class SceneEditInfo implements Serializable {
     private String loadingLogoFile;
 
     /**
+     * 用户上传自定义平面图数据
+     */
+    @TableField("floor_plan_upload")
+    private String floorPlanUpload;
+
+    /**
      * 创建时间
      */
     @TableField("create_time")

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

@@ -85,6 +85,12 @@ public class SceneEditInfoExt {
     private Integer surveillances;
 
     /**
+     * 二维码logo路径(oss相对路径)
+     */
+    @TableField("share_logo_img")
+    private String shareLogoImg;
+
+    /**
      * 创建时间
      */
     @TableField("create_time")

+ 19 - 0
src/main/java/com/fdkankan/scene/listener/RabbitMqListener.java

@@ -48,10 +48,29 @@ public class RabbitMqListener {
         log.info("开始消费消息,id:{},queue:{},content:{}", messageId, downloadTourVideoQueue, msg);
         DownloadTourVideo downloadTourVideo = JSON.parseObject(msg, DownloadTourVideo.class);
         downloadTourVideoService.transferTourVideo(downloadTourVideo);
+        log.info("deliverTag:" + message.getMessageProperties().getDeliveryTag());
         channel.basicAck(message.getMessageProperties().getDeliveryTag(), false);
         log.info("结束消费消息,id:{}", messageId);
     }
 
+    /**
+     * 开启了手动确认模式,如果没有手动确认,消费者不会重试,当服务重启时会再次消费,因为rabbitmq认为你还没有处理完你的业务
+     * queuesToDeclare = @Queue("${queue.modeling.modeling-test}"),  如果队列不不存在会自动创建队列
+     * concurrency = "3"    设置消费线程数,每个线程每次只拉取一条消息消费
+     */
+    @RabbitListener(
+        queuesToDeclare = @Queue("test_dsx")
+    )
+    public void test(Channel channel, Message message) throws Exception {
+        String messageId = message.getMessageProperties().getMessageId();
+        String msg = new String(message.getBody(), StandardCharsets.UTF_8);
+        channel.basicAck(message.getMessageProperties().getDeliveryTag(), false);
+        log.info("开始消费消息,id:{},queue:{},content:{}", messageId, "test_dsx", msg);
+        Thread.sleep(10000L);
+        log.info("deliverTag:" + message.getMessageProperties().getDeliveryTag());
+        log.info("结束消费消息,id:{}", messageId);
+    }
+
 
 
 

+ 24 - 0
src/main/java/com/fdkankan/scene/service/IBoxModelService.java

@@ -0,0 +1,24 @@
+package com.fdkankan.scene.service;
+
+import com.fdkankan.scene.vo.BaseJsonDataParamVO;
+import com.fdkankan.scene.vo.DeleteSidParamVO;
+import com.fdkankan.web.response.ResultData;
+import org.springframework.web.multipart.MultipartFile;
+
+/**
+ * <p>
+ * TODO
+ * </p>
+ *
+ * @author dengsixing
+ * @since 2022/10/19
+ **/
+public interface IBoxModelService {
+
+    ResultData uploadBoxModel(String num, String sid, MultipartFile file) throws Exception;
+
+    ResultData saveBoxModel(BaseJsonDataParamVO param) throws Exception;
+
+    ResultData deleteBoxModel(DeleteSidParamVO param) throws Exception;
+
+}

+ 4 - 1
src/main/java/com/fdkankan/scene/service/IScenePlusService.java

@@ -6,6 +6,7 @@ import com.fdkankan.scene.vo.BaseSceneParamVO;
 import java.util.List;
 import com.fdkankan.scene.entity.ScenePlus;
 import com.fdkankan.scene.vo.SceneCheckKeyParamVO;
+import org.springframework.web.multipart.MultipartFile;
 
 /**
  * <p>
@@ -25,10 +26,12 @@ public interface IScenePlusService extends IService<ScenePlus> {
 
     ResultData moveScene(List<String> numList, Long cameraId, Long userId);
 
-    ResultData downLoadZSData(BaseSceneParamVO param) throws Exception;
+    ResultData downLoadZSData(String num) throws Exception;
 
     ScenePlus checkSceneAvail(String num);
 
     ResultData updateViewCount(String num) throws Exception;
 
+    ResultData uploadShareLogo(String num, MultipartFile file) throws Exception;
+
 }

+ 2 - 0
src/main/java/com/fdkankan/scene/service/ISceneProService.java

@@ -47,4 +47,6 @@ public interface ISceneProService extends IService<ScenePro> {
 
     ResultData downloadTexData(String num) throws Exception;
 
+    ScenePro getByNum(String num);
+
 }

+ 1 - 1
src/main/java/com/fdkankan/scene/service/ISurveillanceService.java

@@ -24,6 +24,6 @@ public interface ISurveillanceService extends IService<Surveillance> {
 
     List<SurveillanceVO> listSurveillance(String num);
 
-    Surveillance getBySid(String sid);
+    Surveillance getBySid(String num, String sid);
 
 }

+ 245 - 0
src/main/java/com/fdkankan/scene/service/impl/BoxModelServiceImpl.java

@@ -0,0 +1,245 @@
+package com.fdkankan.scene.service.impl;
+
+import cn.hutool.core.collection.CollUtil;
+import cn.hutool.core.io.FileUtil;
+import cn.hutool.core.util.StrUtil;
+import cn.hutool.core.util.ZipUtil;
+import com.alibaba.fastjson.JSONArray;
+import com.alibaba.fastjson.JSONObject;
+import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
+import com.fdkankan.common.constant.ErrorCode;
+import com.fdkankan.common.constant.OperationType;
+import com.fdkankan.common.constant.ServerCode;
+import com.fdkankan.common.exception.BusinessException;
+import com.fdkankan.common.util.FileUtils;
+import com.fdkankan.common.util.OBJToGLBUtil;
+import com.fdkankan.fyun.face.FYunFileServiceInterface;
+import com.fdkankan.model.constants.ConstantFilePath;
+import com.fdkankan.model.constants.UploadFilePath;
+import com.fdkankan.model.utils.ComputerUtil;
+import com.fdkankan.scene.bean.BoxModelBean;
+import com.fdkankan.scene.entity.SceneEditInfo;
+import com.fdkankan.scene.entity.ScenePlus;
+import com.fdkankan.scene.entity.ScenePlusExt;
+import com.fdkankan.scene.service.IBoxModelService;
+import com.fdkankan.scene.service.ISceneEditInfoService;
+import com.fdkankan.scene.service.IScenePlusExtService;
+import com.fdkankan.scene.service.IScenePlusService;
+import com.fdkankan.scene.vo.BaseJsonDataParamVO;
+import com.fdkankan.scene.vo.DeleteSidParamVO;
+import com.fdkankan.web.response.ResultData;
+import com.google.common.collect.Lists;
+import java.io.File;
+import java.io.IOException;
+import java.util.Arrays;
+import java.util.Calendar;
+import java.util.Comparator;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Objects;
+import java.util.Set;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import org.springframework.web.multipart.MultipartFile;
+
+/**
+ * <p>
+ * TODO
+ * </p>
+ *
+ * @author dengsixing
+ * @since 2022/10/19
+ **/
+@Slf4j
+@Service
+public class BoxModelServiceImpl implements IBoxModelService {
+
+    @Autowired
+    private FYunFileServiceInterface fYunFileService;
+    @Autowired
+    private IScenePlusService scenePlusService;
+    @Autowired
+    private ISceneEditInfoService sceneEditInfoService;
+    @Autowired
+    private IScenePlusExtService scenePlusExtService;
+
+    @Override
+    public ResultData uploadBoxModel(String num, String sid, MultipartFile file) throws Exception {
+
+        ScenePlus scenePlus = scenePlusService.getScenePlusByNum(num);
+        if(Objects.isNull(scenePlus)){
+            throw new BusinessException(ErrorCode.FAILURE_CODE_5005);
+        }
+        ScenePlusExt scenePlusExt = scenePlusExtService.getScenePlusExtByPlusId(scenePlus.getId());
+        String bucket = scenePlusExt.getYunFileBucket();
+
+        if(!file.getOriginalFilename().endsWith(".zip")){
+            throw new BusinessException(ErrorCode.FAILURE_CODE_7015);
+        }
+
+        if(!FileUtils.checkFileSizeIsLimit(file.getSize(), 5, "M")){
+            throw new BusinessException(ErrorCode.FAILURE_CODE_7023, "5M");
+        }
+        String path = String.format(ConstantFilePath.SCENE_USER_PATH_V4, num) + "boxModel/" + sid + "/";
+        String zipPath = path + file.getOriginalFilename();
+        String srcPath = path + "data/";
+        String glbPath = path + sid + ".glb";
+
+        FileUtil.del(path);
+        FileUtil.mkParentDirs(zipPath);
+        file.transferTo(new File(zipPath));
+
+        //解压
+        ZipUtil.unzip(zipPath,srcPath);
+
+        //校验是否包含目录,如果包含目录提示错误
+        File srcFile = new File(srcPath);
+        Arrays.stream(srcFile.listFiles()).forEach(subFile->{
+            if(subFile.isDirectory()){
+                throw new BusinessException(ErrorCode.FAILURE_CODE_5065);
+            }
+        });
+
+        //转glb
+        OBJToGLBUtil.objToGlb(srcPath, glbPath);
+
+        if(!ComputerUtil.checkComputeCompleted(glbPath, 3, 2000)){
+            throw new BusinessException(ErrorCode.FAILURE_CODE_7013);
+        }
+
+        //上传glb
+        fYunFileService.uploadFile(bucket, glbPath, String.format(UploadFilePath.USER_EDIT_PATH, num) + "boxModels/" + sid + ".glb");
+
+        return ResultData.ok(sid + ".glb");
+    }
+
+    public static void main(String[] args) {
+        ZipUtil.unzip("F:\\test\\新建文件夹\\police模型\\police模型.zip","F:\\test\\新建文件夹\\police模型\\maps");
+    }
+
+    @Override
+    public ResultData saveBoxModel(BaseJsonDataParamVO param) throws Exception {
+
+        JSONObject data = param.getData();
+        String sid = data.getString("sid");
+        if(StrUtil.isEmpty(sid)){
+            throw new BusinessException(ServerCode.PARAM_REQUIRED, sid);
+        }
+        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 = sceneEditInfoService.getByScenePlusId(scenePlus.getId());
+
+        //生成boxVideos数据
+        String boxPhotos = this.createBoxModels(param.getNum(), scenePlusExt.getYunFileBucket(), sid, data, sceneEditInfo, OperationType.ADDORUPDATE.code());
+
+        //更新数据库
+        this.updateBoxModels(sceneEditInfo, boxPhotos);
+
+        return ResultData.ok();
+    }
+
+    @Override
+    public ResultData deleteBoxModel(DeleteSidParamVO param) throws Exception {
+
+        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 = sceneEditInfoService.getByScenePlusId(scenePlus.getId());
+
+        //根据sid移除json
+        String boxModels = this.createBoxModels(param.getNum(), scenePlusExt.getYunFileBucket(), param.getSid(), null, sceneEditInfo, OperationType.DELETE.code());
+
+        //写数据库
+        this.updateBoxModels(sceneEditInfo, boxModels);
+
+        return ResultData.ok();
+    }
+
+    private void updateBoxModels(SceneEditInfo sceneEditInfo, String boxModels){
+        sceneEditInfoService.update(new LambdaUpdateWrapper<SceneEditInfo>()
+            .set(SceneEditInfo::getBoxModels, boxModels)
+            .setSql("version = version + 1")
+            .eq(SceneEditInfo::getId, sceneEditInfo.getId()));
+    }
+
+    private String createBoxModels(String num, String bucket, String sid, JSONObject data, SceneEditInfo sceneEditInfo, int type) throws Exception{
+
+        String boxModels = null;
+        if(sceneEditInfo != null){
+            boxModels = sceneEditInfo.getBoxModels();
+        }
+        JSONArray boxModelsJson = null;
+        if (StrUtil.isNotEmpty(boxModels)) {
+            boxModelsJson = JSONArray.parseArray(boxModels);
+        }else {
+            boxModelsJson = new JSONArray();
+        }
+
+        String result = null;
+        //删除
+        if(type == OperationType.DELETE.code()){
+            Set<String> deleteFile = new HashSet<>();
+            if(boxModelsJson.size() == 0)
+                return null;
+            for(int i=0;i<boxModelsJson.size();++i){
+                JSONObject ele = boxModelsJson.getJSONObject(i);
+                if(ele.getString("sid").equals(sid)){
+                    boxModelsJson.remove(i);
+                    deleteFile.add(String.format(UploadFilePath.USER_EDIT_PATH, num) + sid + ".glb");
+                }
+            }
+            //删除资源文件
+            if(CollUtil.isNotEmpty(deleteFile))
+                deleteFile.stream().forEach(key -> {
+                    try {
+                        fYunFileService.deleteFile(bucket, key);
+                    } catch (IOException e) {
+                        log.warn("oss删除文件失败,key:{}", key);
+                    }
+                });
+        }else{
+            //更新
+            boolean exist = false;
+            for(int i=0;i<boxModelsJson.size();++i){
+                JSONObject ele = boxModelsJson.getJSONObject(i);
+                if(ele.getString("sid").equals(sid)){
+                    data.put("createTime", ele.getLong("createTime"));
+                    boxModelsJson.set(i, data);
+                    exist = true;
+                }
+            }
+            //新增
+            if(!exist){
+                data.put("createTime", Calendar.getInstance().getTimeInMillis());
+                boxModelsJson.add(data);
+            }
+
+        }
+        if(boxModelsJson.size() != 0){
+
+            List<BoxModelBean> list = Lists.newArrayList();
+            for (Object o : boxModelsJson) {
+                JSONObject jsonObject = (JSONObject)o;
+                list.add(BoxModelBean.builder().createTime(jsonObject.getLong("createTime")).boxModel(jsonObject).build());
+            }
+            //按创建时间倒叙排序
+            list.sort(Comparator.comparingLong(BoxModelBean::getCreateTime).reversed());
+
+            // list转JSONArray
+            JSONArray array = new JSONArray();
+            list.stream().forEach(bean->{
+                array.add(bean.getBoxModel());
+            });
+
+            result = array.toJSONString();
+        }
+
+        return result;
+    }
+}

+ 29 - 18
src/main/java/com/fdkankan/scene/service/impl/SceneEditInfoServiceImpl.java

@@ -263,6 +263,7 @@ public class SceneEditInfoServiceImpl extends ServiceImpl<ISceneEditInfoMapper,
         SceneJsonBean sceneJson = new SceneJsonBean();
         BeanUtil.copyProperties(sceneEditInfoExt, sceneJson);
         BeanUtil.copyProperties(sceneEditInfo, sceneJson);
+        sceneJson.setFloorPlanUpload(JSON.parseArray(sceneEditInfo.getFloorPlanUpload()));
         SceneEditControlsVO sceneEditControlsVO = BeanUtil.copyProperties(sceneEditControls, SceneEditControlsVO.class);
         sceneJson.setControls(sceneEditControlsVO);
         sceneJson.setNum(num);
@@ -379,23 +380,28 @@ public class SceneEditInfoServiceImpl extends ServiceImpl<ISceneEditInfoMapper,
     private void publicHotData(String sceneNum, SceneEditInfo sceneEditInfo, String bucket) throws IOException {
         String hotDataKey = String.format(RedisKey.SCENE_HOT_DATA, sceneNum);
         Map<String, String> hotMap = redisUtil.hmget(hotDataKey);
-        List<String> hotList = Lists.newArrayList();
-        hotMap.entrySet().stream().forEach(entry->{
-            if(StrUtil.isNotEmpty(entry.getValue())){
-                hotList.add(entry.getValue());
-            }
-        });
-        if(CollUtil.isNotEmpty(hotList)){
-            JSONArray jsonhots = new JSONArray();
-            hotList.stream().forEach(hot->{
-                jsonhots.add(JSONObject.parseObject(hot));
-            });
-            String hotJsonPath = String.format(UploadFilePath.USER_EDIT_PATH, sceneNum) + "hot.json";
-            fYunFileService.uploadFile(bucket, jsonhots.toString().getBytes(), hotJsonPath);
 
-            //修改tags状态为是,标识有热点数据
-            this.saveTagsToSceneEditInfo(sceneNum, sceneEditInfo);
+        JSONArray tags = new JSONArray();
+        if(CollUtil.isNotEmpty(hotMap)){
+            List<TagBean> tagBeanList = hotMap.entrySet().stream().map(entry -> {
+                JSONObject jsonObject = JSON.parseObject(entry.getValue());
+                return TagBean.builder()
+                    .createTime(jsonObject.getLong("createTime"))
+                    .tag(jsonObject).build();
+            }).collect(Collectors.toList());
+            //按创建时间倒叙排序
+            tagBeanList.sort(Comparator.comparingLong(TagBean::getCreateTime).reversed());
+
+            //移除createTime字段
+            tagBeanList.stream().forEach(tagBean -> {
+                tags.add(tagBean.getTag());
+            });
         }
+
+        String hotJsonPath = String.format(UploadFilePath.USER_EDIT_PATH, sceneNum) + "hot.json";
+        fYunFileService.uploadFile(bucket, tags.toString().getBytes(), hotJsonPath);
+        this.saveTagsToSceneEditInfo(sceneNum, sceneEditInfo);
+
     }
 
     @Override
@@ -438,6 +444,7 @@ public class SceneEditInfoServiceImpl extends ServiceImpl<ISceneEditInfoMapper,
         SceneInfoVO sceneInfoVO = new SceneInfoVO();
         BeanUtil.copyProperties(sceneEditInfoExt, sceneInfoVO);
         BeanUtil.copyProperties(sceneEditInfo, sceneInfoVO);
+        sceneInfoVO.setFloorPlanUpload(JSON.parseArray(sceneEditInfo.getFloorPlanUpload()));
         if(Objects.isNull(sceneInfoVO.getFloorPlanAngle())){
             sceneInfoVO.setFloorPlanAngle(0f);
         }
@@ -452,7 +459,9 @@ public class SceneEditInfoServiceImpl extends ServiceImpl<ISceneEditInfoMapper,
         sceneInfoVO.setSceneFrom(scenePlusExt.getSceneFrom());
         sceneInfoVO.setSceneKind(scenePlusExt.getSceneKind());
         sceneInfoVO.setVideos(scenePlusExt.getVideos());
-        sceneInfoVO.setMosaicList(this.getMosaicList(num));
+        if(CommonStatus.YES.code().equals(sceneEditInfoExt.getMosaic())){
+            sceneInfoVO.setMosaicList(this.getMosaicList(num));
+        }
 
         this.SortBoxVideos(sceneInfoVO);
 
@@ -603,7 +612,9 @@ public class SceneEditInfoServiceImpl extends ServiceImpl<ISceneEditInfoMapper,
         if(StrUtil.isNotEmpty(floorJsonData)){
             JSONObject houseTypeJson = CreateHouseJsonUtil
                 .createHouseTypeJsonByUser(localDataPath + "floorplan_user.json");
-            fYunFileService.uploadFile(bucket, houseTypeJson.toJSONString().getBytes(), editUserPath + "houseType.json");
+            if(Objects.nonNull(houseTypeJson)) {
+                fYunFileService.uploadFile(bucket, houseTypeJson.toJSONString().getBytes(), editUserPath + "houseType.json");
+            }
 
             floorPlanUser = CommonStatus.YES.code();
         }
@@ -1571,7 +1582,7 @@ public class SceneEditInfoServiceImpl extends ServiceImpl<ISceneEditInfoMapper,
 
             //安居客算法运行
             log.info("安居客算法:开始建模——"+num);
-            CreateObjUtil.build3dModel(target , "1");
+            CreateObjUtil.build3dModelOld(target , "1");
             String uploadJsonPath = target + File.separator + "results" + File.separator + "upload.json";
             log.info("uploadJsonPath=" + uploadJsonPath);
             //因为共享目录有延迟,这里循环检测算法是否计算完毕3次,每次隔五秒

+ 83 - 5
src/main/java/com/fdkankan/scene/service/impl/ScenePlusServiceImpl.java

@@ -1,7 +1,10 @@
 package com.fdkankan.scene.service.impl;
 
 import cn.hutool.core.bean.BeanUtil;
+import cn.hutool.core.io.FileUtil;
 import cn.hutool.core.util.StrUtil;
+import cn.hutool.extra.qrcode.QrCodeUtil;
+import cn.hutool.extra.qrcode.QrConfig;
 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
@@ -9,6 +12,13 @@ import com.fdkankan.common.constant.ErrorCode;
 import com.fdkankan.common.constant.PayStatus;
 import com.fdkankan.common.constant.SceneStatus;
 import com.fdkankan.common.exception.BusinessException;
+import com.fdkankan.fyun.face.FYunFileServiceInterface;
+import com.fdkankan.model.constants.ConstantFilePath;
+import com.fdkankan.model.constants.UploadFilePath;
+import com.fdkankan.scene.entity.SceneEditInfoExt;
+import com.fdkankan.scene.entity.ScenePro;
+import com.fdkankan.scene.service.ISceneEditInfoExtService;
+import com.fdkankan.scene.service.ISceneProService;
 import com.fdkankan.web.response.ResultData;
 import com.fdkankan.redis.constant.RedisKey;
 import com.fdkankan.redis.constant.RedisLockKey;
@@ -26,11 +36,15 @@ import com.fdkankan.scene.service.IScenePlusService;
 import com.fdkankan.scene.vo.BaseSceneParamVO;
 import com.fdkankan.scene.vo.SceneCheckKeyParamVO;
 import com.fdkankan.scene.vo.SceneDataDownloadVO;
+import java.io.File;
 import java.util.List;
 import java.util.Objects;
+import java.util.UUID;
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
 import org.springframework.stereotype.Service;
+import org.springframework.web.multipart.MultipartFile;
 
 /**
  * <p>
@@ -44,6 +58,11 @@ import org.springframework.stereotype.Service;
 @Service
 public class ScenePlusServiceImpl extends ServiceImpl<IScenePlusMapper, ScenePlus> implements IScenePlusService {
 
+    @Value("${main.url}")
+    private String mainUrl;
+    @Value("${scene.pro.new.url}")
+    private String sceneProNewUrl;
+
     @Autowired
     private IScenePlusExtService scenePlusExtService;
     @Autowired
@@ -56,6 +75,12 @@ public class ScenePlusServiceImpl extends ServiceImpl<IScenePlusMapper, ScenePlu
     private RedisUtil redisUtil;
     @Autowired
     private RedisLockUtil redisLockUtil;
+    @Autowired
+    private ISceneProService sceneProService;
+    @Autowired
+    private FYunFileServiceInterface fYunFileService;
+    @Autowired
+    private ISceneEditInfoExtService sceneEditInfoExtService;
 
     @Override
     public ScenePlus getScenePlusByNum(String num) {
@@ -105,19 +130,30 @@ public class ScenePlusServiceImpl extends ServiceImpl<IScenePlusMapper, ScenePlu
     }
 
     @Override
-    public ResultData downLoadZSData(BaseSceneParamVO param) throws Exception {
-        String num = param.getNum();
+    public ResultData downLoadZSData(String num) throws Exception {
+
+        if(StrUtil.isEmpty(num)){
+            throw new BusinessException(ErrorCode.FAILURE_CODE_3001);
+        }
+
+        String version = "v4";
         ScenePlus scenePlus = this.getScenePlusByNum(num);
+        ScenePro scenePro = null;
         if(Objects.isNull(scenePlus)){
-            throw new BusinessException(ErrorCode.FAILURE_CODE_5005);
+            scenePro = sceneProService.getByNum(num);
+            version = "v3";
+            if(Objects.isNull(scenePro)){
+                throw new BusinessException(ErrorCode.FAILURE_CODE_5005);
+            }
         }
 
         SceneDataDownload sceneDataDownload = sceneDataDownloadService.findBySceneNum(num);
         if(sceneDataDownload == null){
             throw new BusinessException(ErrorCode.FAILURE_CODE_5025);
         }
-
-        return ResultData.ok(BeanUtil.copyProperties(sceneDataDownload, SceneDataDownloadVO.class));
+        SceneDataDownloadVO sceneDataDownloadVO = BeanUtil.copyProperties(sceneDataDownload, SceneDataDownloadVO.class);
+        sceneDataDownloadVO.setVersion(version);
+        return ResultData.ok(sceneDataDownloadVO);
     }
 
     @Override
@@ -164,4 +200,46 @@ public class ScenePlusServiceImpl extends ServiceImpl<IScenePlusMapper, ScenePlu
         redisUtil.hincr(key, sceneNum, 1);
         return ResultData.ok();
     }
+
+    @Override
+    public ResultData uploadShareLogo(String num, MultipartFile file) throws Exception {
+
+        ScenePlus scenePlus = this.getScenePlusByNum(num);
+        if (Objects.isNull(scenePlus)) {
+            return ResultData.error(ErrorCode.FAILURE_CODE_5005);
+        }
+        ScenePlusExt scenePlusExt = scenePlusExtService.getScenePlusExtByPlusId(scenePlus.getId());
+        SceneEditInfoExt sceneEditInfoExt = sceneEditInfoExtService.getByScenePlusId(scenePlus.getId());
+
+        String fileName = file.getOriginalFilename();
+        String extName = fileName.substring(fileName.lastIndexOf("."));
+        File newFile = File.createTempFile(UUID.randomUUID().toString() ,extName);
+        file.transferTo(newFile);
+
+        String logoPath = newFile.getPath();
+
+        String outPathZh = ConstantFilePath.BASE_PATH + File.separator + "sceneQRcode/"+num+".png";
+        String outPathEn = ConstantFilePath.BASE_PATH + File.separator + "sceneQRcode/"+num+"_en.png";
+
+        String webSize = mainUrl + "/" + sceneProNewUrl + num;
+        QrCodeUtil.generate(webSize, QrConfig.create().setImg(logoPath), FileUtil.file(outPathZh));
+        QrCodeUtil.generate(webSize + "&lang=en", QrConfig.create().setImg(logoPath), FileUtil.file(outPathEn));
+        //上传logo图片
+        String ossLogoPath = String.format(UploadFilePath.DOWNLOADS_QRCODE, num) + "shareLogo" + extName;
+        fYunFileService.uploadFile(scenePlusExt.getYunFileBucket(), logoPath, ossLogoPath);
+
+        //上传二维码
+        fYunFileService.uploadFile(scenePlusExt.getYunFileBucket(), outPathZh, String.format(UploadFilePath.DOWNLOADS_QRCODE, num) + num + ".png");
+        fYunFileService.uploadFile(scenePlusExt.getYunFileBucket(), outPathEn, String.format(UploadFilePath.DOWNLOADS_QRCODE, num) + num + "_en.png");
+
+        sceneEditInfoExt.setShareLogoImg(ossLogoPath);
+        sceneEditInfoExtService.updateById(sceneEditInfoExt);
+
+        FileUtil.del(newFile);
+        FileUtil.del(new File(outPathEn));
+        FileUtil.del(new File(outPathZh));
+
+
+        return ResultData.ok();
+    }
 }

+ 6 - 0
src/main/java/com/fdkankan/scene/service/impl/SceneProServiceImpl.java

@@ -7,6 +7,7 @@ import cn.hutool.core.util.ZipUtil;
 import com.alibaba.fastjson.JSON;
 import com.alibaba.fastjson.JSONArray;
 import com.alibaba.fastjson.JSONObject;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
 import com.fdkankan.common.constant.CommonStatus;
@@ -1003,4 +1004,9 @@ public class SceneProServiceImpl extends ServiceImpl<ISceneProMapper, ScenePro>
         }
         return ResultData.ok(url);
     }
+
+    @Override
+    public ScenePro getByNum(String num) {
+        return this.getOne(new LambdaQueryWrapper<ScenePro>().eq(ScenePro::getNum, num));
+    }
 }

+ 3 - 3
src/main/java/com/fdkankan/scene/service/impl/SurveillanceServiceImpl.java

@@ -49,7 +49,7 @@ public class SurveillanceServiceImpl extends ServiceImpl<ISurveillanceMapper, Su
         }
         SceneEditInfoExt sceneEditInfoExt = sceneEditInfoExtService.getByScenePlusId(scenePlus.getId());
 
-        Surveillance surveillance = this.getBySid(param.getSid());
+        Surveillance surveillance = this.getBySid(param.getNum(), param.getSid());
         if(Objects.isNull(surveillance)){
             surveillance = new Surveillance();
         }
@@ -100,8 +100,8 @@ public class SurveillanceServiceImpl extends ServiceImpl<ISurveillanceMapper, Su
     }
 
     @Override
-    public Surveillance getBySid(String sid) {
-        return this.getOne(new LambdaQueryWrapper<Surveillance>().eq(Surveillance::getSid, sid));
+    public Surveillance getBySid(String num, String sid) {
+        return this.getOne(new LambdaQueryWrapper<Surveillance>().eq(Surveillance::getSid, sid).eq(Surveillance::getNum, num));
     }
 
 }

+ 25 - 0
src/main/java/com/fdkankan/scene/vo/BaseJsonDataParamVO.java

@@ -0,0 +1,25 @@
+package com.fdkankan.scene.vo;
+
+import com.alibaba.fastjson.JSONObject;
+import javax.validation.constraints.NotBlank;
+import javax.validation.constraints.NotNull;
+import lombok.Data;
+
+/**
+ * <p>
+ * 通用data类型参数类
+ * </p>
+ *
+ * @author dengsixing
+ * @since 2022/2/10
+ **/
+@Data
+public class BaseJsonDataParamVO {
+
+    @NotBlank(message = "场景码不能为空")
+    private String num;
+
+    @NotNull(message = "数据不能为空")
+    private JSONObject data;
+
+}

+ 3 - 1
src/main/java/com/fdkankan/scene/vo/SceneDataDownloadVO.java

@@ -5,9 +5,11 @@ import lombok.Data;
 @Data
 public class SceneDataDownloadVO {
 
-    private String num;
+    private String sceneNum;
 
     private String fileMd5;
 
     private String downloadPath;
+
+    private String version;
 }

+ 5 - 0
src/main/java/com/fdkankan/scene/vo/SceneEditInfoParamVO.java

@@ -66,6 +66,11 @@ public class SceneEditInfoParamVO extends BaseSceneParamVO{
      */
     private String loadingLogoFile;
 
+    /**
+     * 用户上传自定义平面图数据
+     */
+    private String floorPlanUpload;
+
     private SceneEditControlsParamVO controls;
 
 

+ 11 - 0
src/main/java/com/fdkankan/scene/vo/SceneInfoVO.java

@@ -1,5 +1,6 @@
 package com.fdkankan.scene.vo;
 
+import com.alibaba.fastjson.JSONArray;
 import com.alibaba.fastjson.JSONObject;
 import java.util.List;
 import lombok.AllArgsConstructor;
@@ -143,6 +144,11 @@ public class SceneInfoVO {
     private String boxPhotos;
 
     /**
+     * 空间模型数据
+     */
+    private String boxModels;
+
+    /**
      *点位视频
      */
     private String videos;
@@ -178,6 +184,11 @@ public class SceneInfoVO {
     private Float floorPlanCompass;
 
     /**
+     * 用户上传自定义平面图
+     */
+    private JSONArray floorPlanUpload;
+
+    /**
      * 是否保存导览
      */
     private Integer tours;

+ 10 - 55
src/main/resources/bootstrap-test-eur.yml

@@ -3,14 +3,11 @@ spring:
     name: 4dkankan-center-scene
   cloud:
     nacos:
+      server-addr: 120.24.144.164:8848
+      namespace: 4dkankan-v4-test-eur
       config:
-        server-addr: 120.24.144.164:8848
         file-extension: yaml
-        namespace: 4dkankan-test-eur
-        extension-configs:
-          - data-id: 4dkankan-center-scene.yaml
-            group: DEFAULT_GROUP
-            refresh: true
+        namespace: ${spring.cloud.nacos.namespace}
         shared-configs:
           - data-id: common-db-config.yaml
             group: DEFAULT_GROUP
@@ -20,61 +17,19 @@ spring:
             group: DEFAULT_GROUP
             refresh: true
 
-          - data-id: other-config.yaml
+          - data-id: common-config.yaml
             group: DEFAULT_GROUP
             refresh: true
 
-          - data-id: common-upload-config.yaml
+          - data-id: common-fyun-config.yaml
             group: DEFAULT_GROUP
             refresh: true
-      discovery:
-        server-addr: 120.24.144.164:8848
-        namespace: 4dkankan-test-eur
-#    sentinel:
-#      transport:
-#        dashboard: 120.24.144.164:8888
-#        heartbeat-interval-ms: 500
-#        port: 8719
-#      eager: true #取消sentinel控制台懒加载
-#      #sentinel配置持久化nacos
-#      datasource:
-#        #流控规则
-#        flow:
-#          nacos:
-#            server-addr: ${spring.cloud.nacos.config.server-addr}
-#            dataId: ${spring.application.name}-flow-rules
-#            groupId: SENTINEL_GROUP
-#            namespace: 4dkankan-test
-#            rule-type: flow
-#        #熔断规则
-#        degrade:
-#          nacos:
-#            server-addr: ${spring.cloud.nacos.config.server-addr}
-#            dataId: ${spring.application.name}-degrade-rules
-#            groupId: SENTINEL_GROUP
-#            namespace: 4dkankan-test
-#            rule-type: degrade
-#      log:
-#        dir: ./logs # 默认值${home}/logs/csp/
-#        switch-pid: true # 日志带上线程id
-
-#开启feign熔断降级,如果没有开启,feign调用链路不会显示再sentinel控制中
-#feign:
-#  sentinel:
-#    enabled: true
 
-feign:
-  httpclient:
-    connection-timeout: 200000
-
-server:
-  tomcat:
-    threads:
-      min-spare: 100  #最小工作线程数
-      max: 1000       #最大工作线程数,建议配置为cpu核心数的200~250倍
-    accept-count: 1000   #能够接受的最大等待数,默认100。如果等待队列也被放满了,新的请求会被tomcat拒绝(connection refused)
-    max-connections: 2000   #同一时间,tomcat能够接受的最大连接数。一般这个值要大于(max-threads)+(accept-count)
-    connection-timeout: 3000  #连接建立超时时间
+          - data-id: common-rabbitmq-config.yaml
+            group: DEFAULT_GROUP
+            refresh: true
+      discovery:
+        namespace: ${spring.cloud.nacos.namespace}
 
 
 

+ 1 - 1
src/main/resources/bootstrap-test.yml

@@ -3,7 +3,7 @@ spring:
     name: 4dkankan-center-scene
   cloud:
     nacos:
-      server-addr: 172.20.1.63:8848
+      server-addr: 120.24.144.164:8848
       namespace: 4dkankan-v4-test
       config:
         file-extension: yaml