Browse Source

上传e57

dengsixing 6 months ago
parent
commit
337b9d9c2e

+ 11 - 0
src/main/java/com/fdkankan/contro/controller/SceneFileController.java

@@ -80,6 +80,17 @@ public class SceneFileController{
         return sceneFileBuildService.turntableUploadSuccess(params);
         return sceneFileBuildService.turntableUploadSuccess(params);
     }
     }
 
 
+    /**
+     *
+     *
+     * @param params
+     * @return
+     */
+    @PostMapping("reverseScene")
+    public ResultData reverseScene(@RequestBody JSONObject params) throws Exception {
+        return sceneFileBuildService.reverseScene(params);
+    }
+
     @GetMapping("rebuildScene")
     @GetMapping("rebuildScene")
     public ResultData rebuildScene(@RequestParam(value = "num") String num,
     public ResultData rebuildScene(@RequestParam(value = "num") String num,
                                    @RequestParam(value = "force",defaultValue = "false") Boolean force ,
                                    @RequestParam(value = "force",defaultValue = "false") Boolean force ,

+ 7 - 1
src/main/java/com/fdkankan/contro/entity/ScenePlus.java

@@ -12,7 +12,7 @@ import java.util.Date;
  * 场景主表
  * 场景主表
  * </p>
  * </p>
  *
  *
- * @author 
+ * @author
  * @since 2022-03-16
  * @since 2022-03-16
  */
  */
 @Getter
 @Getter
@@ -116,5 +116,11 @@ public class ScenePlus implements Serializable {
     @TableLogic("A")
     @TableLogic("A")
     private String recStatus;
     private String recStatus;
 
 
+    @TableField("other_type")
+    private String otherType;
+
+    @TableField("source_id")
+    private Long sourceId;
+
 
 
 }
 }

+ 116 - 0
src/main/java/com/fdkankan/contro/mq/listener/BuildReverseE57Listener.java

@@ -0,0 +1,116 @@
+package com.fdkankan.contro.mq.listener;
+
+import cn.hutool.core.exceptions.ExceptionUtil;
+import com.alibaba.fastjson.JSON;
+import com.alibaba.fastjson.JSONObject;
+import com.fdkankan.common.constant.CommonOperStatus;
+import com.fdkankan.contro.mq.service.impl.BuildReverseE57SceneServiceImpl;
+import com.fdkankan.contro.service.ICommonService;
+import com.fdkankan.contro.service.ISceneBuildProcessLogService;
+import com.fdkankan.model.constants.SceneBuildProcessType;
+import com.fdkankan.rabbitmq.bean.BuildSceneCallMessage;
+import com.fdkankan.rabbitmq.bean.BuildSceneResultMqMessage;
+import com.rabbitmq.client.Channel;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.amqp.core.Message;
+import org.springframework.amqp.rabbit.annotation.Queue;
+import org.springframework.amqp.rabbit.annotation.RabbitListener;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.stereotype.Component;
+import org.springframework.util.ObjectUtils;
+
+import java.nio.charset.StandardCharsets;
+import java.util.HashMap;
+
+@Slf4j
+@Component
+public class BuildReverseE57Listener {
+
+    @Value("${queue.modeling.reverseE57.modeling-pre:reverseE57-modeling-pre}")
+    private String queueModelingPre;
+
+    @Value("${queue.modeling.reverseE57.modeling-post:reverseE57-modeling-post}")
+    private String queueModelingPost;
+
+    @Autowired
+    private ISceneBuildProcessLogService sceneBuildProcessLogService;
+    @Autowired
+    private ICommonService commonService;
+    @Autowired
+    private BuildReverseE57SceneServiceImpl buildSceneService;
+
+
+    /**
+     * 场景计算前置资源准备处理
+     * @param channel
+     * @param message
+     * @throws Exception
+     */
+    @RabbitListener(
+            queuesToDeclare = @Queue("${queue.modeling.reverseE57.modeling-pre:reverseE57-modeling-pre}"),
+            concurrency = "${maxThread.modeling.modeling-pre}"
+    )
+    public void buildScenePreHandler(Channel channel, Message message) throws Exception {
+        String messageId = message.getMessageProperties().getMessageId();
+        String msg = new String(message.getBody(), StandardCharsets.UTF_8);
+        HashMap<String, Object> map = JSON.parseObject(msg, HashMap.class);
+        String num = (String) map.get("num");
+        map.put("bizType", "reverseE57");
+
+        log.info("开始准备上传e57计算资源,队列名:{},id:{},消息体:{}", queueModelingPre, messageId, msg);
+        BuildSceneCallMessage buildSceneMessage = new BuildSceneCallMessage();
+        buildSceneMessage.setSceneNum(num);
+        buildSceneMessage.setExt(map);
+        buildSceneMessage.setBuildType("V3");
+        try {
+            if(ObjectUtils.isEmpty(buildSceneMessage.getBuildContext())){
+                buildSceneMessage.setBuildContext(new HashMap<>());
+            }
+            if(!ObjectUtils.isEmpty(buildSceneMessage.getSceneNum())){
+                buildSceneMessage.getBuildContext().put("sceneNum",buildSceneMessage.getSceneNum());
+            }
+            //记录日志
+            sceneBuildProcessLogService.clearSceneBuildProcessLog(num, SceneBuildProcessType.PRE.code(), queueModelingPre, "reverseE57");
+            sceneBuildProcessLogService.saveSceneBuildProcessLog(num, SceneBuildProcessType.PRE.code(), queueModelingPre, CommonOperStatus.WAITING.code(), null, "reverseE57");
+            buildSceneService.buildScenePre(buildSceneMessage);
+            commonService.saveMqSendLog(num, buildSceneMessage);
+            sceneBuildProcessLogService.saveSceneBuildProcessLog(num, SceneBuildProcessType.PRE.code(), queueModelingPre, CommonOperStatus.SUCCESS.code(), null, "reverseE57");
+        }catch (Exception e){
+            log.error("上传e57计算前置处理出错,num=" + num, e);
+            sceneBuildProcessLogService.saveSceneBuildProcessLog(num, SceneBuildProcessType.PRE.code(), queueModelingPre, CommonOperStatus.FAILD.code(), ExceptionUtil.stacktraceToString(e, 3000), "reverseE57");
+        }
+        log.info("准备上传e57计算资源完成,队列名:{},id:{},消息体:{}", queueModelingPre, messageId, msg);
+        channel.basicAck(message.getMessageProperties().getDeliveryTag(), false);
+    }
+
+    /**
+     * 场景计算后置结果处理
+     * @param channel
+     * @param message
+     * @throws Exception
+     */
+    @RabbitListener(
+            queuesToDeclare = @Queue("${queue.modeling.reverseE57.modeling-post:reverseE57-modeling-post}"),
+            concurrency = "${maxThread.modeling.modeling-post}"
+    )
+    public void buildScenePostHandler(Channel channel, Message message) throws Exception {
+        String messageId = message.getMessageProperties().getMessageId();
+        String msg = new String(message.getBody(), StandardCharsets.UTF_8);
+        log.info("场景计算完成,开始处理e57计算结果,队列名:{},id:{},消息体:{}", queueModelingPost, messageId, msg);
+        BuildSceneResultMqMessage buildSceneMessage = JSONObject.parseObject(msg, BuildSceneResultMqMessage.class);
+        String num = buildSceneMessage.getBuildContext().get("sceneNum").toString();
+        try {
+            sceneBuildProcessLogService.clearSceneBuildProcessLog(num, SceneBuildProcessType.POST.code(), queueModelingPost, "reverseE57");
+            sceneBuildProcessLogService.saveSceneBuildProcessLog(num, SceneBuildProcessType.POST.code(), queueModelingPost, CommonOperStatus.WAITING.code(), null, "reverseE57");
+            buildSceneService.buildScenePost(buildSceneMessage);
+            sceneBuildProcessLogService.saveSceneBuildProcessLog(num, SceneBuildProcessType.POST.code(), queueModelingPost, CommonOperStatus.SUCCESS.code(), null, "reverseE57");
+        }catch (Exception e){
+            log.error("场景计算结果处理出错,num=" + num, e);
+            sceneBuildProcessLogService.saveSceneBuildProcessLog(num, SceneBuildProcessType.POST.code(), queueModelingPost, CommonOperStatus.FAILD.code(), ExceptionUtil.stacktraceToString(e, 3000), "reverseE57");
+        }
+        log.info("场景计算结果处理完成,队列名:{},id:{},消息体:{}", queueModelingPost, messageId, msg);
+        channel.basicAck(message.getMessageProperties().getDeliveryTag(), false);
+
+    }
+}

+ 498 - 0
src/main/java/com/fdkankan/contro/mq/service/impl/BuildReverseE57SceneServiceImpl.java

@@ -0,0 +1,498 @@
+package com.fdkankan.contro.mq.service.impl;
+
+import cn.hutool.core.collection.CollUtil;
+import cn.hutool.core.io.FileUtil;
+import cn.hutool.core.util.CharsetUtil;
+import cn.hutool.core.util.StrUtil;
+import cn.hutool.core.util.ZipUtil;
+import cn.hutool.extra.qrcode.QrCodeUtil;
+import cn.hutool.extra.qrcode.QrConfig;
+import cn.hutool.http.HttpUtil;
+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.*;
+import com.fdkankan.common.util.FileUtils;
+import com.fdkankan.contro.bean.SyncLaserResultBean;
+import com.fdkankan.contro.constant.UserEditDataType;
+import com.fdkankan.contro.entity.*;
+import com.fdkankan.contro.mq.service.IBuildSceneService;
+import com.fdkankan.contro.service.*;
+import com.fdkankan.contro.service.impl.CommonServiceImpl;
+import com.fdkankan.fyun.config.FYunFileConfig;
+import com.fdkankan.fyun.face.FYunFileServiceInterface;
+import com.fdkankan.model.constants.ConstantFileName;
+import com.fdkankan.model.constants.ConstantFilePath;
+import com.fdkankan.model.constants.UploadFilePath;
+import com.fdkankan.model.enums.ModelTypeEnums;
+import com.fdkankan.model.utils.CreateHouseJsonUtil;
+import com.fdkankan.model.utils.CreateObjUtil;
+import com.fdkankan.rabbitmq.bean.BuildSceneCallMessage;
+import com.fdkankan.rabbitmq.bean.BuildSceneResultMqMessage;
+import com.fdkankan.rabbitmq.util.RabbitMqProducer;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.lang3.ObjectUtils;
+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 javax.annotation.Resource;
+import java.io.File;
+import java.io.IOException;
+import java.nio.charset.StandardCharsets;
+import java.util.*;
+
+
+/**
+ * <p>
+ * TODO
+ * </p>
+ *
+ * @author dengsixing
+ * @since 2022/4/20
+ **/
+@Slf4j
+@Service
+@RefreshScope
+public class BuildReverseE57SceneServiceImpl implements IBuildSceneService {
+    public static final String logUrlFormat = "**algorithm-log**: [%sbuild_log/%s/e57/console.log](%sbuild_log/%s/e57/console.log)";
+
+    @Value("${queue.modeling.reverseE57.modeling-post:reverseE57-modeling-post}")
+    private String queueModelingPost;
+    @Value("#{'${build.scene.post.not-delete-nas-nums:}'.split(',')}")
+    private List<String> notDeleteNasNumList;
+    @Value("${queue.application.laser.e57-modeling-done:e57-modeling-done}")
+    private String queueE57ModelingDone;
+    @Autowired
+    private RabbitMqProducer mqProducer;
+    @Value("${model.type:#{null}}")
+    private String modelType;
+    @Resource
+    private FYunFileServiceInterface fYunFileService;
+    @Autowired
+    private FYunFileConfig fYunFileConfig;
+    @Autowired
+    private IScenePlusService scenePlusService;
+    @Autowired
+    private IScenePlusExtService scenePlusExtService;
+    @Autowired
+    private IBuildSceneDTService buildSceneDTService;
+    @Autowired
+    private ICommonService commonService;
+    @Autowired
+    private IFdkkLaserService fdkkLaserService;
+    @Autowired
+    private ISceneEditControlsService sceneEditControlsService;
+
+    @Value("${main.url}")
+    private String mainUrl;
+    @Override
+    public void buildScenePre(BuildSceneCallMessage message) throws Exception{
+        String num = message.getSceneNum();
+        ScenePlus scenePlus = scenePlusService.getScenePlusByNum(num);
+        ScenePlusExt scenePlusExt = scenePlusExtService.getScenePlusExtByPlusId(scenePlus.getId());
+        try {
+            String dataSource = scenePlusExt.getDataSource();
+            message.setPath(dataSource);
+
+            String key = (String)message.getExt().get("path");
+
+            //下载资源到本地
+            String destPath = dataSource + "/capture/";
+            fYunFileService.downloadFileByCommand(destPath, key);
+            List<File> files = FileUtil.loopFiles(dataSource + "/capture/");
+            files.stream().forEach(file->{
+                if(file.getAbsolutePath().endsWith(".e57")){
+                    FileUtil.rename(file, "input.e57", true);
+                }
+            });
+
+            //发送mq,就进行计算
+//            message.setPath(path);
+            message.setResultReceiverMqName(queueModelingPost);
+            message.setBizType("reverseE57");
+
+            log.info("上传e57计算资源准备结束,场景码:{}", message.getSceneNum());
+
+        }catch (Exception e){
+            log.error("上传e57计算前置处理出错,num"+num, e);
+            scenePlus.setSceneStatus(CommonSuccessStatus.FAIL.code());
+            scenePlusService.updateById(scenePlus);
+            fdkkLaserService.sendE57ToLaser(scenePlus, scenePlusExt, null);
+            buildSceneDTService.handBaseFail("上传e57计算资源准备异常!", message.getPath(), message.getSceneNum(), "计算控制服务器");
+            throw e;
+        }
+    }
+
+    private String getOssPath(String path) {
+        String ossPath = ConstantFilePath.OSS_PREFIX
+                + path.replace(ConstantFilePath.BUILD_MODEL_PATH, "")
+                .replace(ConstantFilePath.BUILD_MODEL_LASER_PATH, "");
+        if (!ossPath.endsWith("/")) {
+            ossPath = ossPath.concat("/");
+        }
+        return ossPath;
+    }
+
+    @Override
+    public void downLoadSource(BuildSceneCallMessage buildSceneMqMessage,String path){
+        String ossPath = getOssPath(buildSceneMqMessage.getPath());
+        fYunFileService.downloadFileByCommand(path + "/capture", ossPath);
+    }
+
+    @Override
+    public void buildScenePost(BuildSceneResultMqMessage message) throws Exception {
+        String sceneCode = message.getBuildContext().get("sceneNum").toString();
+        String path = message.getPath();
+        ScenePlus scenePlus = scenePlusService.getScenePlusByNum(sceneCode);
+        ScenePlusExt scenePlusExt = scenePlusExtService.getScenePlusExtByPlusId(scenePlus.getId());
+        try {
+            // 上传计算日志
+            //如果是重复计算,没有走到计算逻辑,不需要上传日志文件
+            log.info("开始上传计算日志");
+            String buildLogPath = String.format(UploadFilePath.BUILD_LOG_PATH, sceneCode);
+            fYunFileService.uploadFile(path + File.separator + "console.log", buildLogPath + "console.log");
+            log.info("计算日志上传完成");
+
+            if (!message.getBuildSuccess()) {
+                log.error("建模失败,修改状态为失败状态");
+                scenePlus.setSceneStatus(CommonSuccessStatus.FAIL.code());
+                scenePlusService.updateById(scenePlus);
+                fdkkLaserService.sendE57ToLaser(scenePlus, scenePlusExt, null);
+
+                // 发送钉钉消息,计算失败
+                buildSceneDTService.handModelFail("计算失败", message.getPath(), sceneCode, message.getHostName());
+                return;
+            }
+
+            JSONObject fdageData = new JSONObject();
+            fdageData.put("exportMeshObj", 1);
+            Map<String, String> uploadFiles = commonService.getUploadFiles(scenePlus,path,14,fdageData);
+
+            String rebuild = message.getRebuild();
+            //新拍场景默认是已支付状态,补拍、重算的场景,支付状态无需改变
+            if("0".equals(rebuild)){
+                log.info("是新拍");
+                scenePlus.setPayStatus(PayStatus.PAY.code());
+            }
+            scenePlus.setUpdateTime(new Date());
+            scenePlus.setSceneStatus(SceneStatus.NO_DISPLAY.code());
+
+//            Integer videoVersion = fdageData.getInteger("videoVersion");
+//            //读取计算结果文件生成videosJson
+//            JSONObject videosJson = null;
+
+            boolean isObj = fdageData.containsKey("exportMeshObj") && fdageData.getIntValue("exportMeshObj") == 1;
+
+            //上传全景图俯视图
+            this.uploadFloorCad(path, sceneCode, uploadFiles);
+
+            log.info("开始上传场景计算结果数据,num:{}", sceneCode);
+            //由于3dtiles算法mesh文件发生变化,所以这里需要先清除一下oss的mesh目录,避免存在旧算法obj文件
+            fYunFileService.deleteFolder(String.format(UploadFilePath.DATA_VIEW_PATH, sceneCode) + "mesh");
+            fYunFileService.deleteFolder(String.format(UploadFilePath.IMG_VIEW_PATH,  sceneCode) + ModelKind.THREE_D_TILE.code());
+            //上传文件
+            fYunFileService.uploadMulFiles(uploadFiles);
+
+            //修改oss上dam的内容编码
+            Map<String,String> damFileHeaders = new HashMap<>();
+            damFileHeaders.put("Content-Encoding","gzip");
+            String damPath = path + File.separator + "results" + File.separator + ConstantFileName.modelUUID + "_50k.dam";
+            fYunFileService.uploadFile(damPath,  String.format(UploadFilePath.IMG_VIEW_PATH, sceneCode) + ConstantFileName.modelUUID + "_50k.dam", damFileHeaders);
+
+            //拷贝部分文件到编辑目录,用于用户编辑
+            this.copyToEditDir(sceneCode);
+
+            //计算完毕后,同步全景图到缓存目录
+//            this.cachePanorama(path, sceneCode);
+
+            //生成houseTypejson并上传
+            boolean existHouseType = this.uploadHouseTypeJson(sceneCode, path);
+            scenePlus.setHouseType(existHouseType ? CommonStatus.YES.code().intValue() : CommonStatus.NO.code().intValue());
+
+            //生成floorpan.json
+            commonService.uploadFloorplanJson(sceneCode, path);
+
+            //重置异步操作记录
+            commonService.removeSceneAsynOperLog(sceneCode);
+
+            //清除用户编辑业务数据
+            Set<String> bizs = new HashSet<>();
+            bizs.add(UserEditDataType.BOX_MODEL.message());
+            bizs.add(UserEditDataType.FLOORPLAN.message());
+            bizs.add(UserEditDataType.FILTERS.message());
+            commonService.initUserEditData(sceneCode, bizs, null);
+
+            //上传计算结果文件
+            commonService.uploadBuildResultData(sceneCode, path, SceneVersionType.V4.code());
+
+            //容量统计
+            Long space = commonService.getSpace(sceneCode);
+
+            //写入数据库
+            this.updateDbPlus(scenePlus.getSceneSource(), space, null, message.getComputeTime(),isObj,scenePlusExt);
+
+            Object[] editInfoArr = commonService.updateEditInfo(scenePlus);
+            SceneEditInfo sceneEditInfo = (SceneEditInfo)editInfoArr[0];
+            SceneEditInfoExt sceneEditInfoExt = (SceneEditInfoExt)editInfoArr[1];
+            SceneEditControls sceneEditControls = (SceneEditControls)editInfoArr[2];
+
+            //更新场景主表
+            //如果相机容量不足,需要把场景的paystatus改为容量不足状态
+//            scenePlus.setPayStatus(commonService.getPayStatus(scenePlus.getCameraId(), space));
+            //统计原始资源大小
+            scenePlusExt.setOrigSpace(FileUtil.size(new File(path.concat(File.separator).concat("capture"))));
+            scenePlusExt.setWebSite(mainUrl + "/smg.html?m=" + sceneCode);
+
+            String visionTxt = FileUtil.readUtf8String(path + "/results/vision.txt");
+            JSONObject visionObj = JSON.parseObject(visionTxt);
+            JSONArray sweepLocations = visionObj.getJSONArray("sweepLocations");
+            scenePlusExt.setShootCount(sweepLocations.size());
+
+            String laserPath = fdkkLaserService.syncBuildResult4E57(path);
+            fdkkLaserService.sendE57ToLaser(scenePlus, scenePlusExt, laserPath);
+            sceneEditControlsService.update(new LambdaUpdateWrapper<SceneEditControls>().set(SceneEditControls::getShowMap,0)
+                    .eq(SceneEditControls::getEditInfoId,sceneEditInfo.getId()));
+            sceneEditControls.setShowMap(0);
+
+
+            log.info("生成scene.json上传oss并设置缓存,num:{}", sceneCode);
+            //写scene.json
+            commonService.writeSceneJson(sceneCode,sceneEditInfo, sceneEditInfoExt, sceneEditControls, scenePlus,scenePlusExt, null);
+
+            createQrCode(sceneCode, scenePlusExt, null);
+
+            this.uploadStatusJson(scenePlus, scenePlusExt);
+
+            scenePlusService.updateById(scenePlus);
+            scenePlusExtService.updateById(scenePlusExt);
+
+            log.info("场景计算结果处理结束,场景码:{}", sceneCode);
+
+        }catch (Exception e){
+            log.error("场景计算结果处理出错,num"+sceneCode, e);
+            scenePlus.setSceneStatus(CommonSuccessStatus.FAIL.code());
+            scenePlusService.updateById(scenePlus);
+            fdkkLaserService.sendE57ToLaser(scenePlus, scenePlusExt, null);
+            buildSceneDTService.handBaseFail("场景计算结果处理出错!", message.getPath(), sceneCode, "计算控制服务器");
+            throw e;
+        }
+    }
+
+    public boolean uploadHouseTypeJson(String num, String dataSource) {
+        String floorPlanCardFilePath = dataSource + File.separator + "results/floorplan_cad.json";
+        if (!new File(floorPlanCardFilePath).exists()) {
+            log.warn("floorplan_cad.json 文件不存在,文件路径:{}", floorPlanCardFilePath);
+            return false;
+        }
+        JSONObject json = CreateHouseJsonUtil.createHouseTypeJsonByCad(floorPlanCardFilePath);
+        if(Objects.isNull(json)){
+            return false;
+        }
+        String hourseTypeJsonPath = String.format(UploadFilePath.USER_VIEW_PATH, num) + "houseType.json";
+        fYunFileService.uploadFile(json.toJSONString().getBytes(), hourseTypeJsonPath);
+        hourseTypeJsonPath = String.format(UploadFilePath.USER_EDIT_PATH, num) + "houseType.json";
+        fYunFileService.uploadFile(json.toJSONString().getBytes(), hourseTypeJsonPath);
+
+        return true;
+    }
+
+    private void updateDbPlus(int sceneSource,Long space,String videosJson, Long computeTime,boolean isObj,ScenePlusExt scenePlusExt){
+
+        scenePlusExt.setSpace(space);
+        scenePlusExt.setComputeTime(computeTime.toString());
+        scenePlusExt.setAlgorithmTime(new Date());
+        scenePlusExt.setVideos(videosJson);
+        scenePlusExt.setIsObj(isObj ? 1 : 0);
+
+        if(ModelTypeEnums.TILE_CODE.equals(modelType)){
+            scenePlusExt.setSceneScheme(3);
+        }
+
+        scenePlusExt.setSceneResolution(SceneResolution.four_K.code());
+        scenePlusExt.setSceneFrom(SceneFrom.LASER.code());
+
+        String sceneKind = scenePlusExt.getSceneScheme() == 3 ? SceneKind.FACE.code():SceneKind.TILES.code();
+        scenePlusExt.setSceneKind(sceneKind);
+//        scenePlusExt.setModelKind(modelKind);
+
+        //统计点位数量
+        scenePlusExtService.updateById(scenePlusExt);
+    }
+
+    private void copyToEditDir(String num) throws IOException {
+
+        String editImagesPath = String.format(UploadFilePath.IMG_EDIT_PATH, num);
+        String viewImagesPath = String.format(UploadFilePath.IMG_VIEW_PATH, num);
+
+        String editDataPath = String.format(UploadFilePath.DATA_EDIT_PATH, num);
+        String viewDataPath = String.format(UploadFilePath.DATA_VIEW_PATH, num);
+
+        Map<String, String> map = new HashMap<>();
+        map.put(editImagesPath + "vision.modeldata", viewImagesPath + "vision.modeldata");
+        map.put(editImagesPath + "vision2.modeldata", viewImagesPath + "vision2.modeldata");
+        map.put(editDataPath + "floorplan_cad.json", viewDataPath + "floorplan_cad.json");
+
+        for (Map.Entry<String, String> entry : map.entrySet()) {
+            fYunFileService.copyFileInBucket(entry.getValue(), entry.getKey());
+        }
+    }
+
+    private void createQrCode(String num, ScenePlusExt scenePlusExt, String qrLogo) {
+        String localLogoPath = null;
+        if (!ObjectUtils.isEmpty(qrLogo)) {
+            try {
+                localLogoPath = ConstantFilePath.AGENT_PATH + qrLogo.substring(qrLogo.lastIndexOf("//") + 1);
+                HttpUtil.downloadFile(qrLogo, localLogoPath);
+            } catch (Exception e) {
+                log.error("公司logo下载失败:{}", qrLogo);
+                localLogoPath = null;
+            }
+        }
+        //生成二维码
+        String outPathZh = ConstantFilePath.BASE_PATH + File.separator + "sceneQRcode/"+ num +".png";
+        String outPathEn = ConstantFilePath.BASE_PATH + File.separator + "sceneQRcode/"+ num +"_en.png";
+        QrConfig qrConfig = QrConfig.create();
+        qrConfig.setWidth(1024);
+        qrConfig.setHeight(1024);
+        if(StrUtil.isNotEmpty(localLogoPath)){
+            qrConfig.setImg(localLogoPath);
+        }
+        QrCodeUtil.generate(scenePlusExt.getWebSite(), qrConfig, FileUtil.file(outPathZh));
+        QrCodeUtil.generate(scenePlusExt.getWebSite() + "&lang=en", qrConfig, FileUtil.file(outPathEn));
+        //上传二维码
+        fYunFileService.uploadFile(outPathZh, String.format(UploadFilePath.DOWNLOADS_QRCODE, num) + num + ".png");
+        fYunFileService.uploadFile(outPathEn, String.format(UploadFilePath.DOWNLOADS_QRCODE, num) + num + "_en.png");
+
+        if(!ObjectUtils.isEmpty(localLogoPath)){
+            FileUtils.deleteFile(localLogoPath);
+        }
+    }
+
+    private void uploadFloorCad(String path, String num, Map<String, String> uploadFiles){
+
+        //户型图上传
+        String  dataViewPath = UploadFilePath.DATA_VIEW_PATH + "floor-cad-%s.%s";
+        String floorCadPath = path + "/results/floorplan_cad";
+        List<String> floorCadList = FileUtils.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(dataViewPath, num, arr2[0], arr2[1]));
+            });
+        }
+
+    }
+
+    private void uploadStatusJson(ScenePlus scenePlus, ScenePlusExt scenePlusExt){
+        String num = scenePlus.getNum();
+        String dataViewPath = String.format(UploadFilePath.DATA_VIEW_PATH, num);
+
+        Integer status = 0;
+
+        // 上传status JSON.
+        JSONObject statusJson = new JSONObject();
+        //临时将-2改成1,app还没完全更新
+        statusJson.put("status", status);
+        statusJson.put("webSite", scenePlusExt.getWebSite());
+        statusJson.put("sceneNum", num);
+        statusJson.put("thumb", scenePlusExt.getThumb());
+        statusJson.put("payStatus", scenePlus.getPayStatus());
+        statusJson.put("sceneScheme", scenePlusExt.getSceneScheme());
+        FileUtils.writeFile(ConstantFilePath.SCENE_PATH + "data/data" + num + File.separator + "status.json", statusJson.toString());
+
+        fYunFileService.uploadFile(statusJson.toJSONString().getBytes(StandardCharsets.UTF_8), dataViewPath + "status.json");
+    }
+
+    private Map<String, String> getUploadFiles(ScenePlus scenePlus,String path) throws Exception {
+        if (ObjectUtils.isEmpty(scenePlus)) {
+            throw new Exception("未找到场景信息:" + path);
+        }
+
+        String projectNum = scenePlus.getNum();
+
+        String dataViewPath = String.format(UploadFilePath.DATA_VIEW_PATH, projectNum);
+        String imagesPath = String.format(UploadFilePath.IMG_VIEW_PATH, projectNum);
+        String videoPath = String.format(UploadFilePath.VIDEOS_VIEW_PATH, projectNum);
+        String resultsPath = path + File.separator + "results" + File.separator;
+
+        String uploadData = FileUtils.readFile(resultsPath + "upload.json");
+        JSONArray array = JSONObject.parseObject(uploadData).getJSONArray("upload");
+
+        JSONObject fileJson = null;
+        String fileName = "";
+
+        Map<String, String> map = new HashMap();
+
+        for (int i = 0; i < array.size(); ++i) {
+            fileJson = array.getJSONObject(i);
+            fileName = fileJson.getString("file");
+            String filePath = resultsPath + fileName;
+
+            if (!(new File(filePath)).exists()) {
+                throw new Exception(filePath + "文件不存在");
+            }
+
+            if ("vision2.txt".equals(fileName)) {
+                CreateObjUtil.convertTxtToVisionmodeldata(resultsPath + "vision2.txt", resultsPath + "vision2.modeldata");
+                map.put(resultsPath + "vision2.modeldata", imagesPath + "vision2.modeldata");
+                map.put(resultsPath + "vision2.txt", imagesPath + "vision2.txt");
+            }
+
+            if (fileJson.getIntValue("clazz") == 2) {
+                map.put(filePath, imagesPath + ConstantFileName.modelUUID + "_50k_texture_jpg_high1/" + fileName.replace("tex/", ""));
+            } else if (fileJson.getIntValue("clazz") == 3) {
+                map.put(filePath, imagesPath + "pan/high/" + fileName.replace("high/", ""));
+            } else if (fileJson.getIntValue("clazz") == 4) {
+                map.put(filePath, imagesPath + "pan/low/" + fileName.replace("low/", ""));
+            } else if (fileJson.getIntValue("clazz") == 5) {
+                map.put(filePath, imagesPath + fileName);
+            } else if (fileJson.getIntValue("clazz") == 7) {
+                map.put(filePath, imagesPath + fileName);
+            } else if (fileJson.getIntValue("clazz") == 10) {
+                String updown = FileUtils.readFile(filePath);
+                JSONObject updownJson = JSONObject.parseObject(updown);
+                String mappingOssPath = String.format("scene_edit_data/%s/data/", projectNum) + fileName.replace("updown", "mapping");
+                map.put(filePath, mappingOssPath);
+            } else {
+                if (fileJson.getIntValue("clazz") == 11 || fileJson.getIntValue("clazz") == 12) {
+                    map.put(filePath, videoPath + fileName.replace("videos/", ""));
+                    if (fileName.contains(".mp4")) {
+                        map.put(resultsPath + fileName.replace("mp4", "flv"), videoPath + fileName.replace("videos/", "").replace("mp4", "flv"));
+                    }
+                }
+
+                if (fileJson.getIntValue("clazz") == 16) {
+                    map.put(filePath, dataViewPath + fileName);
+                }
+
+                if (fileJson.getIntValue("clazz") == 18) {
+                    map.put(filePath, imagesPath + fileName);
+                }
+            }
+        }
+
+        CreateObjUtil.convertTxtToVisionmodeldata(resultsPath + "vision.txt", resultsPath + "vision.modeldata");
+        map.put(resultsPath + "vision.txt", imagesPath + "vision.txt");
+        map.put(resultsPath + "vision.modeldata", imagesPath + "vision.modeldata");
+
+        log.info("数据转换完成:" + projectNum);
+        if(!new File("/mnt/4Dkankan/scene/data" + File.separator + "data" + projectNum).exists()){
+            FileUtil.mkdir("/mnt/4Dkankan/scene/data" + File.separator + "data" + projectNum);
+        }
+//        map.put(resultsPath + "floorplan.json", dataViewPath + "floor.json");
+        map.put(resultsPath + "floorplan_cad.json", dataViewPath + "floorplan_cad.json");
+        map.put(path + File.separator + "capture/stitch_params.txt", dataViewPath + "stitch_params.txt");
+        map.put(path + File.separator + "capture/Up.xml", dataViewPath + "Up.xml");
+        map.put(path + File.separator + "capture/Up2.xml", dataViewPath + "Up2.xml");
+        map.put(path + File.separator + "capture/Up.txt", dataViewPath + "Up.txt");
+        map.put(path + File.separator + "capture/Up2.txt", dataViewPath + "Up2.txt");
+        return map;
+
+    }
+
+}

+ 4 - 0
src/main/java/com/fdkankan/contro/service/IFdkkLaserService.java

@@ -20,6 +20,8 @@ import java.util.Date;
 public interface IFdkkLaserService {
 public interface IFdkkLaserService {
     void syncBuildResult(SyncLaserResultBean laserResultBean);
     void syncBuildResult(SyncLaserResultBean laserResultBean);
 
 
+    String syncBuildResult4E57(String dataSource);
+
     void pushBuildStatusToLaserSystem(String projectNum, String laserObjFilePath, Integer buildObjStatus);
     void pushBuildStatusToLaserSystem(String projectNum, String laserObjFilePath, Integer buildObjStatus);
 
 
     void saveScene(ScenePlus scenePlus, JSONObject jsonObject, Camera cameraEntity, String userName, boolean b, Integer payStatus);
     void saveScene(ScenePlus scenePlus, JSONObject jsonObject, Camera cameraEntity, String userName, boolean b, Integer payStatus);
@@ -27,4 +29,6 @@ public interface IFdkkLaserService {
     void saveScene(ScenePro scenePro, String scenePassword, Camera cameraEntity, String phone, boolean rebuild, Integer payStatus);
     void saveScene(ScenePro scenePro, String scenePassword, Camera cameraEntity, String phone, boolean rebuild, Integer payStatus);
 
 
     void cloudPointBuild(String sceneCode, String visionEditFilePath);
     void cloudPointBuild(String sceneCode, String visionEditFilePath);
+
+    void sendE57ToLaser(ScenePlus scenePlus, ScenePlusExt scenePlusExt, String path);
 }
 }

+ 3 - 0
src/main/java/com/fdkankan/contro/service/ISceneFileBuildService.java

@@ -1,5 +1,6 @@
 package com.fdkankan.contro.service;
 package com.fdkankan.contro.service;
 
 
+import com.alibaba.fastjson.JSONObject;
 import com.baomidou.mybatisplus.extension.service.IService;
 import com.baomidou.mybatisplus.extension.service.IService;
 import com.fdkankan.contro.entity.SceneFileBuild;
 import com.fdkankan.contro.entity.SceneFileBuild;
 import com.fdkankan.contro.vo.ResponseSceneFile;
 import com.fdkankan.contro.vo.ResponseSceneFile;
@@ -30,4 +31,6 @@ public interface ISceneFileBuildService extends IService<SceneFileBuild> {
     ResultData copyDataAndBuild(String sourceBucet,String dataSource,String sceneVer) throws Exception;
     ResultData copyDataAndBuild(String sourceBucet,String dataSource,String sceneVer) throws Exception;
 
 
     ResultData uploadLiguang(String num, String snCode, String ossPath) throws Exception;
     ResultData uploadLiguang(String num, String snCode, String ossPath) throws Exception;
+
+    ResultData reverseScene(JSONObject params) throws Exception;
 }
 }

+ 69 - 8
src/main/java/com/fdkankan/contro/service/impl/IFdkkLaserServiceImpl.java

@@ -3,18 +3,13 @@ package com.fdkankan.contro.service.impl;
 import cn.hutool.core.io.FileUtil;
 import cn.hutool.core.io.FileUtil;
 import com.alibaba.fastjson.JSONObject;
 import com.alibaba.fastjson.JSONObject;
 import com.fdkankan.common.constant.CommonStatus;
 import com.fdkankan.common.constant.CommonStatus;
+import com.fdkankan.common.constant.SceneStatus;
 import com.fdkankan.common.constant.SceneVersionType;
 import com.fdkankan.common.constant.SceneVersionType;
 import com.fdkankan.common.util.DateUtil;
 import com.fdkankan.common.util.DateUtil;
 import com.fdkankan.common.util.FileUtils;
 import com.fdkankan.common.util.FileUtils;
 import com.fdkankan.contro.bean.SyncLaserResultBean;
 import com.fdkankan.contro.bean.SyncLaserResultBean;
-import com.fdkankan.contro.entity.Camera;
-import com.fdkankan.contro.entity.ScenePlus;
-import com.fdkankan.contro.entity.ScenePlusExt;
-import com.fdkankan.contro.entity.ScenePro;
-import com.fdkankan.contro.service.IFdkkLaserService;
-import com.fdkankan.contro.service.IScenePlusExtService;
-import com.fdkankan.contro.service.IScenePlusService;
-import com.fdkankan.contro.service.ISceneProService;
+import com.fdkankan.contro.entity.*;
+import com.fdkankan.contro.service.*;
 import com.fdkankan.fyun.face.FYunFileServiceInterface;
 import com.fdkankan.fyun.face.FYunFileServiceInterface;
 import com.fdkankan.rabbitmq.util.RabbitMqProducer;
 import com.fdkankan.rabbitmq.util.RabbitMqProducer;
 import lombok.extern.slf4j.Slf4j;
 import lombok.extern.slf4j.Slf4j;
@@ -62,6 +57,8 @@ public class IFdkkLaserServiceImpl implements IFdkkLaserService {
 
 
     @Value("${4dkk.laserService.cloud-point-fyun-path}")
     @Value("${4dkk.laserService.cloud-point-fyun-path}")
     private String cloudPointFyunPath;
     private String cloudPointFyunPath;
+    @Autowired
+    private IUserService userService;
 
 
     @Resource
     @Resource
     private FYunFileServiceInterface fYunFileService;
     private FYunFileServiceInterface fYunFileService;
@@ -219,4 +216,68 @@ public class IFdkkLaserServiceImpl implements IFdkkLaserService {
         params.put("businessType", 0);
         params.put("businessType", 0);
         rabbitMqProducer.sendByWorkQueue(cloudPointBuild, params);
         rabbitMqProducer.sendByWorkQueue(cloudPointBuild, params);
     }
     }
+
+    public void sendE57ToLaser(ScenePlus scenePlus, ScenePlusExt scenePlusExt, String path) {
+        User user = userService.getById(scenePlus.getUserId());
+        Map<String, Object> params = new HashMap<>();
+        params.put("createTime", DateUtil.date2String(scenePlus.getCreateTime(), null));
+        params.put("phone", user.getUserName());
+        params.put("sceneCode", scenePlus.getNum());
+        params.put("status", -scenePlus.getSceneStatus());
+        params.put("version",getSceneVersion(scenePlus.getNum()));
+        params.put("title", scenePlus.getTitle());
+        params.put("userId", scenePlus.getUserId());
+        params.put("sceneSource", scenePlus.getSceneSource());
+        params.put("location", scenePlusExt.getLocation());
+        params.put("payStatus", scenePlus.getPayStatus());
+        params.put("shootCount", scenePlusExt.getShootCount());
+        params.put("path", path);
+        if(scenePlus.getSceneStatus() == SceneStatus.wait.code()){
+            rabbitMqProducer.sendByWorkQueue("laser-e57-init-scene", params);
+        }
+        if(scenePlus.getSceneStatus() == SceneStatus.NO_DISPLAY.code() || scenePlus.getSceneStatus() == SceneStatus.FAILD.code()){
+            rabbitMqProducer.sendByWorkQueue("laser-e57-update-scene", params);
+        }
+    }
+
+    public String syncBuildResult4E57(String dataSource) {
+        log.info("激光转台相机构建结果 同步 请求 ");
+        try {
+            String jgPath = dataSource;
+            //创建目录
+            if (dataSource.lastIndexOf("/") != -1) {
+                jgPath = jgPath + "_laserData";
+            } else {
+                jgPath = jgPath.substring(0, jgPath.length() - 1) + "_laserData";
+            }
+
+            FileUtils.createDir(jgPath + "/extras");
+
+            log.info("生成 激光相机目录 " + jgPath);
+            //生成data.json
+            JSONObject jgDataJson = new JSONObject();
+            jgDataJson.put("split_type", "SPLIT_V15");
+            jgDataJson.put("skybox_type", "SKYBOX_V5");
+            jgDataJson.put("extras", null);
+            FileUtils.writeFile(jgPath + File.separator + "data.json", jgDataJson.toString());
+
+            // result/mesh/mesh.obj  --> jgPath/laserData/laser.obj
+            log.info("开始拷贝obj文件");
+            FileUtils.copyDirectiory(dataSource + "/results/mesh", jgPath + "/laserData/mesh");
+
+            FileUtils.copyDirectiory(dataSource + "/results/laserData/cover", jgPath + "/extras");
+            //删除旧的深度图
+            if(FileUtil.exist( jgPath+"/laserData/depthmap/")){
+                FileUtil.del(jgPath+"/laserData/depthmap/");
+            }
+            FileUtils.copyFile(dataSource + "/results/laserData", jgPath, true);
+
+            return jgPath + "/laserData";
+
+        } catch (Exception e) {
+            log.error("激光转台相机同步失败", e);
+        }
+
+        return null;
+    }
 }
 }

+ 76 - 0
src/main/java/com/fdkankan/contro/service/impl/SceneFileBuildServiceImpl.java

@@ -864,6 +864,82 @@ public class SceneFileBuildServiceImpl extends ServiceImpl<ISceneFileBuildMapper
         return ResultData.ok();
         return ResultData.ok();
     }
     }
 
 
+    @Override
+    public ResultData reverseScene(JSONObject params) throws Exception {
+
+        String title = params.getString("title");
+        Long userId = params.getLong("userId");
+        String otherType = params.getString("otherType");//AZ
+        String path = params.getString("path");
+        Long sourceId = params.getLong("sourceId");
+        Integer isObj = params.getIntValue("isObj");
+        String buildType = "V3";
+
+        String num = scene3dNumService.generateSceneNum(null);
+        ScenePlus scenePlus = new ScenePlus();
+        ScenePlusExt scenePlusExt = new ScenePlusExt();
+        SceneEditInfo sceneEditInfo = new SceneEditInfo();
+        SceneEditInfoExt sceneEditInfoExt = new SceneEditInfoExt();
+        SceneEditControls sceneEditControls = new SceneEditControls();
+        scenePlus.setTitle(title);
+        scenePlus.setUserId(userId);
+        scenePlus.setPayStatus(PayStatus.PAY.code());
+        scenePlus.setSceneStatus(CommonOperStatus.WAITING.code());
+        scenePlus.setOtherType(otherType);
+        scenePlus.setSourceId(sourceId);
+        if("AZ".equals(otherType)){
+            num = "AZ-" + num;
+            scenePlus.setSceneSource(SceneSource.ZT.code());
+            scenePlusExt.setSceneFrom(SceneFrom.MINION.code());
+            scenePlusExt.setModelKind(ModelKind.DAM.code());
+        }else{
+            num = "e57-" + num;
+            scenePlus.setSceneSource(57);
+            scenePlusExt.setSceneFrom(SceneFrom.LASER.code());
+            scenePlusExt.setModelKind(ModelKind.THREE_D_TILE.code());
+        }
+        params.put("num", num);
+
+        SSOUser user = userService.getSSOUserByUserId(userId);
+
+        scenePlus.setNum(num);
+        scenePlus.setCreateTime(new Date());
+        scenePlusService.save(scenePlus);
+
+        StringBuilder prefixBuffer = new StringBuilder(ConstantFilePath.BUILD_MODEL_PATH).append("reverseScene/").append(UUID.randomUUID());
+        scenePlusExt.setSceneKind(SceneKind.TILES.code());
+        scenePlusExt.setSceneResolution(SceneResolution.four_K.code());
+        scenePlusExt.setBuildType(buildType);
+        scenePlusExt.setLocation(4);
+        scenePlusExt.setSceneScheme(SceneScheme.FOUR_K.code());
+        scenePlusExt.setPlusId(scenePlus.getId());
+        scenePlusExt.setDataSource(prefixBuffer.toString());
+        scenePlusExt.setIsObj(isObj);
+        scenePlusExtService.save(scenePlusExt);
+
+
+        sceneEditInfo.setTitle(title);
+        sceneEditInfo.setScenePlusId(scenePlus.getId());
+        sceneEditInfoService.save(sceneEditInfo);
+
+        sceneEditInfoExt.setScenePlusId(scenePlus.getId());
+        sceneEditInfoExt.setEditInfoId(sceneEditInfo.getId());
+        sceneEditInfoExtService.save(sceneEditInfoExt);
+
+        sceneEditControls.setEditInfoId(sceneEditInfo.getId());
+        sceneEditControlsService.save(sceneEditControls);
+
+        if("AZ".equals(otherType)){
+            rabbitMqProducer.sendByWorkQueue("reverse-scene", params);
+        }else{
+            fdkkLaserService.sendE57ToLaser(scenePlus, scenePlusExt, null);
+            rabbitMqProducer.sendByWorkQueue("reverseE57-modeling-pre", params);
+        }
+
+
+        return ResultData.ok();
+    }
+
     public ScenePlusVO createScenePlus(String projectNum, Long cameraId, String phoneId, String sceneKey,
     public ScenePlusVO createScenePlus(String projectNum, Long cameraId, String phoneId, String sceneKey,
                                      Long cameraType, int camType, String dataSource, String pic, Long userId, String userName,
                                      Long cameraType, int camType, String dataSource, String pic, Long userId, String userName,
                                      String algorithm, Integer location, Integer sceneShootCount, String sceneName,
                                      String algorithm, Integer location, Integer sceneShootCount, String sceneName,