소스 검색

空间模型功能

dengsixing 2 년 전
부모
커밋
460b72330b

+ 27 - 0
4dkankan-center-scene/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;
+
+}

+ 5 - 0
4dkankan-center-scene/src/main/java/com/fdkankan/scene/bean/SceneJsonBean.java

@@ -133,6 +133,11 @@ public class SceneJsonBean {
     private String boxPhotos;
 
     /**
+     * 空间模型数据
+     */
+    private String boxModels;
+
+    /**
      *点位视频
      */
     private String videos;

+ 58 - 0
4dkankan-center-scene/src/main/java/com/fdkankan/scene/controller/SceneEditController.java

@@ -6,6 +6,7 @@ import com.fdkankan.common.controller.BaseController;
 import com.fdkankan.common.exception.BusinessException;
 import com.fdkankan.common.response.ResultData;
 import com.fdkankan.scene.annotation.CheckCooperationPermit;
+import com.fdkankan.scene.service.IBoxModelService;
 import com.fdkankan.scene.service.IDownloadTourVideoService;
 import com.fdkankan.scene.service.ISceneEditInfoService;
 import com.fdkankan.scene.service.ISceneEditService;
@@ -13,6 +14,7 @@ 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.BaseJsonDataParamVO;
 import com.fdkankan.scene.vo.BaseSidParamVO;
 import com.fdkankan.scene.vo.SurveillanceParamVO;
 import com.fdkankan.scene.vo.BallScreenVideoParamVO;
@@ -82,6 +84,8 @@ public class SceneEditController extends BaseController {
     private IScenePlusService scenePlusService;
     @Autowired
     private IDownloadTourVideoService downloadTourVideoService;
+    @Autowired
+    private IBoxModelService boxModelService;
 
 
     /**
@@ -1151,16 +1155,70 @@ public class SceneEditController extends BaseController {
         return surveillanceService.saveSurveillance(param);
     }
 
+    @CheckCooperationPermit
     @PostMapping("/surveillance/delete")
     public ResultData deleteSurveillance(@RequestBody @Validated BaseSidParamVO param){
         return surveillanceService.deleteSurveillance(param);
     }
 
+    @CheckCooperationPermit
     @PostMapping("/surveillance/list")
     public ResultData listSurveillance(@RequestBody @Validated BaseSceneParamVO param){
         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
+     **/
+    @CheckCooperationPermit
+    @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
+     **/
+    @CheckCooperationPermit
+    @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
+     **/
+    @CheckCooperationPermit
+    @PostMapping("/model/box/delete")
+    public ResultData delBoxModel(@RequestBody @Validated DeleteSidParamVO param) throws Exception {
+        return boxModelService.deleteBoxModel(param);
+    }
+
+
+
 
 
 

+ 7 - 0
4dkankan-center-scene/src/main/java/com/fdkankan/scene/entity/SceneEditInfo.java

@@ -149,6 +149,13 @@ public class SceneEditInfo implements Serializable {
     private String boxPhotos;
 
     /**
+     * 空间模型数据
+     */
+    @TableField("box_models")
+    private String boxModels;
+
+
+    /**
      * 是否需要处理球幕视频
      */
     @TableField("build_video_status")

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

@@ -0,0 +1,26 @@
+package com.fdkankan.scene.service;
+
+import com.fdkankan.common.response.ResultData;
+import com.fdkankan.scene.vo.BaseDataParamVO;
+import com.fdkankan.scene.vo.BaseJsonDataParamVO;
+import com.fdkankan.scene.vo.DeleteSidParamVO;
+import java.io.IOException;
+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;
+
+}

+ 229 - 0
4dkankan-center-scene/src/main/java/com/fdkankan/scene/service/impl/BoxModelServiceImpl.java

@@ -0,0 +1,229 @@
+package com.fdkankan.scene.service.impl;
+
+import cn.hutool.core.collection.CollUtil;
+import cn.hutool.core.img.ImgUtil;
+import cn.hutool.core.io.FileUtil;
+import cn.hutool.core.util.StrUtil;
+import com.alibaba.fastjson.JSON;
+import com.alibaba.fastjson.JSONArray;
+import com.alibaba.fastjson.JSONObject;
+import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
+import com.fdkankan.common.constant.ConstantFilePath;
+import com.fdkankan.common.constant.ErrorCode;
+import com.fdkankan.common.constant.FileBizType;
+import com.fdkankan.common.constant.OperationType;
+import com.fdkankan.common.constant.ServerCode;
+import com.fdkankan.common.constant.UploadFilePath;
+import com.fdkankan.common.exception.BusinessException;
+import com.fdkankan.common.response.ResultData;
+import com.fdkankan.common.util.FileUtils;
+import com.fdkankan.common.util.OBJToGLBUtil;
+import com.fdkankan.fyun.oss.UploadToOssUtil;
+import com.fdkankan.scene.bean.BoxModelBean;
+import com.fdkankan.scene.bean.BoxPhotoBean;
+import com.fdkankan.scene.entity.SceneEditInfo;
+import com.fdkankan.scene.entity.ScenePlus;
+import com.fdkankan.scene.service.IBoxModelService;
+import com.fdkankan.scene.service.ISceneEditInfoService;
+import com.fdkankan.scene.service.IScenePlusService;
+import com.fdkankan.scene.vo.BaseDataParamVO;
+import com.fdkankan.scene.vo.BaseJsonDataParamVO;
+import com.fdkankan.scene.vo.DeleteFileParamVO;
+import com.fdkankan.scene.vo.DeleteSidParamVO;
+import com.google.common.collect.Lists;
+import java.awt.image.BufferedImage;
+import java.io.File;
+import java.io.IOException;
+import java.util.ArrayList;
+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 UploadToOssUtil uploadToOssUtil;
+    @Autowired
+    private IScenePlusService scenePlusService;
+    @Autowired
+    private ISceneEditInfoService sceneEditInfoService;
+
+    @Override
+    public ResultData uploadBoxModel(String num, String sid, MultipartFile file) throws Exception {
+
+        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.mkParentDirs(zipPath);
+        file.transferTo(new File(zipPath));
+
+        //解压
+        FileUtils.decompress(zipPath, srcPath);
+
+        //校验是否包含目录,如果包含目录提示错误
+        List<String> fileList = com.fdkankan.common.util.FileUtil.getFileList(srcPath);
+        if(CollUtil.isNotEmpty(fileList)){
+            fileList.stream().forEach(str -> {
+                if(FileUtil.isDirectory(str)){
+                    throw new BusinessException(ErrorCode.FAILURE_CODE_5065);
+                }
+            });
+        }
+
+        //转glb
+        OBJToGLBUtil.objToGlb(srcPath, glbPath);
+
+        if(!FileUtil.exist(glbPath)){
+            throw new BusinessException(ErrorCode.FAILURE_CODE_7013);
+        }
+
+        //上传glb
+        uploadToOssUtil.upload(glbPath, String.format(UploadFilePath.USER_EDIT_PATH, num) + sid + ".glb");
+
+        return ResultData.ok(sid + ".glb");
+    }
+
+    @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);
+
+        SceneEditInfo sceneEditInfo = sceneEditInfoService.getByScenePlusId(scenePlus.getId());
+
+        //生成boxVideos数据
+        String boxPhotos = this.createBoxModels(param.getNum(), 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);
+
+        SceneEditInfo sceneEditInfo = sceneEditInfoService.getByScenePlusId(scenePlus.getId());
+
+        //根据sid移除json
+        String boxModels = this.createBoxModels(param.getNum(), 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 sid, JSONObject data, SceneEditInfo sceneEditInfo, int type) throws Exception{
+
+        String boxModels = null;
+        if(sceneEditInfo != null){
+            boxModels = sceneEditInfo.getBoxPhotos();
+        }
+        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 {
+                        uploadToOssUtil.delete(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;
+    }
+}

+ 24 - 0
4dkankan-center-scene/src/main/java/com/fdkankan/scene/vo/BaseJsonDataParamVO.java

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

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

@@ -145,6 +145,11 @@ public class SceneInfoVO {
     private String boxPhotos;
 
     /**
+     * 空间模型数据
+     */
+    private String boxModels;
+
+    /**
      *点位视频
      */
     private String videos;