瀏覽代碼

Merge remote-tracking branch 'origin/release-swsx' into release

# Conflicts:
#	pom.xml
#	src/main/java/com/fdkankan/contro/controller/InnerController.java
#	src/main/java/com/fdkankan/contro/entity/ScenePlus.java
#	src/main/java/com/fdkankan/contro/service/impl/CommonServiceImpl.java
#	src/main/java/com/fdkankan/contro/service/impl/SceneFileBuildServiceImpl.java
dengsixing 1 周之前
父節點
當前提交
b4f98c0492
共有 52 個文件被更改,包括 2172 次插入521 次删除
  1. 7 6
      pom.xml
  2. 1 0
      src/main/java/com/fdkankan/contro/ModelingControlApplication.java
  3. 40 0
      src/main/java/com/fdkankan/contro/controller/InnerController.java
  4. 36 0
      src/main/java/com/fdkankan/contro/controller/LaserApiController.java
  5. 10 0
      src/main/java/com/fdkankan/contro/dto/GenerateObjFileDTO.java
  6. 5 2
      src/main/java/com/fdkankan/contro/entity/CameraType.java
  7. 51 0
      src/main/java/com/fdkankan/contro/entity/RelocationBatch.java
  8. 72 0
      src/main/java/com/fdkankan/contro/entity/RelocationBatchDetail.java
  9. 55 0
      src/main/java/com/fdkankan/contro/entity/RelocationInit.java
  10. 7 0
      src/main/java/com/fdkankan/contro/entity/ScenePlus.java
  11. 6 0
      src/main/java/com/fdkankan/contro/entity/ScenePro.java
  12. 16 1
      src/main/java/com/fdkankan/contro/enums/CameraTypeEnum.java
  13. 1 1
      src/main/java/com/fdkankan/contro/generate/AutoGenerate.java
  14. 18 0
      src/main/java/com/fdkankan/contro/mapper/IRelocationBatchDetailMapper.java
  15. 18 0
      src/main/java/com/fdkankan/contro/mapper/IRelocationBatchMapper.java
  16. 18 0
      src/main/java/com/fdkankan/contro/mapper/IRelocationInitMapper.java
  17. 0 1
      src/main/java/com/fdkankan/contro/mq/listener/BuildIntermitSceneListener.java
  18. 169 0
      src/main/java/com/fdkankan/contro/mq/listener/BuildSxRelocationListener.java
  19. 16 0
      src/main/java/com/fdkankan/contro/mq/listener/UpdateSceneStatusListener.java
  20. 14 11
      src/main/java/com/fdkankan/contro/mq/service/impl/BuildE57SceneServiceImpl.java
  21. 29 19
      src/main/java/com/fdkankan/contro/mq/service/impl/BuildIntermitSceneServiceImpl.java
  22. 7 7
      src/main/java/com/fdkankan/contro/mq/service/impl/BuildLiguangServiceImpl.java
  23. 7 1
      src/main/java/com/fdkankan/contro/mq/service/impl/BuildObjServiceImpl.java
  24. 39 9
      src/main/java/com/fdkankan/contro/mq/service/impl/BuildReverseE57SceneServiceImpl.java
  25. 18 4
      src/main/java/com/fdkankan/contro/mq/service/impl/BuildSceneServiceImpl.java
  26. 321 0
      src/main/java/com/fdkankan/contro/mq/service/impl/BuildSxRelocationServiceImpl.java
  27. 4 2
      src/main/java/com/fdkankan/contro/mq/service/impl/BuildV3SceneServiceImpl.java
  28. 26 3
      src/main/java/com/fdkankan/contro/schedule/ScheduleJob.java
  29. 14 0
      src/main/java/com/fdkankan/contro/service/IBuildService.java
  30. 3 1
      src/main/java/com/fdkankan/contro/service/ICameraTypeService.java
  31. 1 0
      src/main/java/com/fdkankan/contro/service/ICommonService.java
  32. 3 2
      src/main/java/com/fdkankan/contro/service/IFdkkLaserService.java
  33. 10 0
      src/main/java/com/fdkankan/contro/service/IGenerateObjFileService.java
  34. 9 0
      src/main/java/com/fdkankan/contro/service/IInnerService.java
  35. 21 0
      src/main/java/com/fdkankan/contro/service/IRelocationBatchDetailService.java
  36. 19 0
      src/main/java/com/fdkankan/contro/service/IRelocationBatchService.java
  37. 19 0
      src/main/java/com/fdkankan/contro/service/IRelocationInitService.java
  38. 114 0
      src/main/java/com/fdkankan/contro/service/impl/BuildServiceImpl.java
  39. 14 1
      src/main/java/com/fdkankan/contro/service/impl/CameraTypeServiceImpl.java
  40. 19 3
      src/main/java/com/fdkankan/contro/service/impl/CommonServiceImpl.java
  41. 149 0
      src/main/java/com/fdkankan/contro/service/impl/GenerateObjFileServiceImpl.java
  42. 21 1
      src/main/java/com/fdkankan/contro/service/impl/IFdkkLaserServiceImpl.java
  43. 70 0
      src/main/java/com/fdkankan/contro/service/impl/InnerServiceImpl.java
  44. 27 0
      src/main/java/com/fdkankan/contro/service/impl/RelocationBatchDetailServiceImpl.java
  45. 84 0
      src/main/java/com/fdkankan/contro/service/impl/RelocationBatchServiceImpl.java
  46. 100 0
      src/main/java/com/fdkankan/contro/service/impl/RelocationInitServiceImpl.java
  47. 272 249
      src/main/java/com/fdkankan/contro/service/impl/SceneFileBuildServiceImpl.java
  48. 5 1
      src/main/resources/bootstrap.yml
  49. 172 196
      src/main/resources/logback-nacos.xml
  50. 5 0
      src/main/resources/mapper/contro/RelocationBatchDetailMapper.xml
  51. 5 0
      src/main/resources/mapper/contro/RelocationBatchMapper.xml
  52. 5 0
      src/main/resources/mapper/contro/RelocationInitMapper.xml

+ 7 - 6
pom.xml

@@ -194,16 +194,17 @@
       <version>2.17.0</version>
     </dependency>
 
+    <!--htt请求工具-->
     <dependency>
-      <groupId>com.fdkankan</groupId>
-      <artifactId>4dkankan-utils-sign</artifactId>
-      <version>3.0.0-SNAPSHOT</version>
+      <groupId>com.dtflys.forest</groupId>
+      <artifactId>forest-spring-boot-starter</artifactId>
+      <version>1.5.24</version>
     </dependency>
 
     <dependency>
-      <groupId>com.dtflys.forest</groupId>
-      <artifactId>forest-spring-boot-starter</artifactId>
-      <version>1.5.19</version>
+      <groupId>com.fdkankan</groupId>
+      <artifactId>4dkankan-utils-sign</artifactId>
+      <version>3.0.0-SNAPSHOT</version>
     </dependency>
 
   </dependencies>

+ 1 - 0
src/main/java/com/fdkankan/contro/ModelingControlApplication.java

@@ -22,6 +22,7 @@ import org.springframework.scheduling.annotation.EnableScheduling;
 @ComponentScan(basePackages = {"com.fdkankan.*"})
 @EnableAsync
 @MapperScan("com.fdkankan.**.mapper")
+@ForestScan(basePackages = "com.fdkankan.contro.httpclient")
 @EnableDiscoveryClient
 @ForestScan(basePackages = "com.fdkankan.contro.httpclient")
 public class ModelingControlApplication {

+ 40 - 0
src/main/java/com/fdkankan/contro/controller/InnerController.java

@@ -1,6 +1,7 @@
 package com.fdkankan.contro.controller;
 
 import com.fdkankan.contro.annotation.SignVerification;
+import com.fdkankan.contro.entity.ScenePlus;
 import com.fdkankan.contro.service.IInnerService;
 import com.fdkankan.web.response.ResultData;
 import lombok.extern.log4j.Log4j2;
@@ -8,6 +9,9 @@ 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;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.List;
 
 /**
  * 场景文件上传模块
@@ -27,5 +31,41 @@ public class InnerController {
         return ResultData.ok();
     }
 
+    /**
+     * 内部用接口,修改场景为计算失败状态,app可以出发补拍重传
+     * @param num
+     * @return
+     * @throws Exception
+     */
+    @GetMapping("updateSceneFail")
+    public ResultData updateSceneFail(String num) throws Exception {
+        innerService.updateSceneFail(num);
+        return ResultData.ok();
+    }
+
+    /**
+     * 只是一个demo接口
+     * @param title
+     * @param type
+     * @return
+     */
+    @GetMapping("listNewCameraScene")
+    public ResultData listNewCameraScene(@RequestParam("title") String title, @RequestParam("type") String type){
+        List<ScenePlus> ScenePlusList = innerService.listNewCameraScene(title, type);
+        return ResultData.ok(ScenePlusList);
+    }
+
+    /**
+     * 只是一个demo接口
+     * @param title
+     * @param type
+     * @return
+     */
+    @PostMapping("submit")
+    public ResultData submit(String sxNum, String qjkkNum){
+        innerService.submit(sxNum, qjkkNum);
+        return ResultData.ok();
+    }
+
 
 }

+ 36 - 0
src/main/java/com/fdkankan/contro/controller/LaserApiController.java

@@ -0,0 +1,36 @@
+package com.fdkankan.contro.controller;
+
+import com.fdkankan.common.constant.ErrorCode;
+import com.fdkankan.contro.dto.GenerateObjFileDTO;
+import com.fdkankan.contro.service.IGenerateObjFileService;
+import com.fdkankan.web.response.Result;
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+@RestController
+@RequestMapping("/api/scene/inner")
+public class LaserApiController {
+
+    @Autowired
+    private IGenerateObjFileService generateObjFileService;
+
+
+    /**
+     *
+     *
+     *
+     * 激光场景生成obj文件
+     */
+    @PostMapping(value = "/generateObjFile")
+    public Result generateObjFile(@RequestBody GenerateObjFileDTO requestScene) throws Exception{
+        String num = requestScene.getSceneNum();
+        if (StringUtils.isEmpty(num)) {
+            return Result.failure(ErrorCode.FAILURE_CODE_3001.code(), ErrorCode.FAILURE_CODE_3001.message());
+        }
+        return generateObjFileService.generateObjFile(num);
+    }
+}

+ 10 - 0
src/main/java/com/fdkankan/contro/dto/GenerateObjFileDTO.java

@@ -0,0 +1,10 @@
+package com.fdkankan.contro.dto;
+
+import lombok.Data;
+
+@Data
+public class GenerateObjFileDTO {
+
+    private String sceneNum;
+
+}

+ 5 - 2
src/main/java/com/fdkankan/contro/entity/CameraType.java

@@ -12,10 +12,10 @@ import lombok.Setter;
 
 /**
  * <p>
- * 
+ *
  * </p>
  *
- * @author 
+ * @author
  * @since 2023-04-11
  */
 @Getter
@@ -62,5 +62,8 @@ public class CameraType implements Serializable {
     @TableField("update_time")
     private Date updateTime;
 
+    @TableField("is_laser")
+    private Integer isLaser;
+
 
 }

+ 51 - 0
src/main/java/com/fdkankan/contro/entity/RelocationBatch.java

@@ -0,0 +1,51 @@
+package com.fdkankan.contro.entity;
+
+import com.baomidou.mybatisplus.annotation.*;
+import lombok.Getter;
+import lombok.Setter;
+
+import java.io.Serializable;
+import java.util.Date;
+
+/**
+ * <p>
+ * 重定位批次表
+ * </p>
+ *
+ * @author 
+ * @since 2025-09-09
+ */
+@Getter
+@Setter
+@TableName("t_relocation_batch")
+public class RelocationBatch implements Serializable {
+
+    private static final long serialVersionUID = 1L;
+
+    @TableId(value = "id", type = IdType.AUTO)
+    private Long id;
+
+    /**
+     * 重定位场景码
+     */
+    @TableField("num")
+    private String num;
+
+    /**
+     * 0-排队中,1-计算中,2-已完成
+     */
+    @TableField("status")
+    private Integer status;
+
+    @TableField("create_time")
+    private Date createTime;
+
+    @TableField("update_time")
+    private Date updateTime;
+
+    @TableField("rec_status")
+    @TableLogic(value = "A", delval = "I")
+    private String recStatus;
+
+
+}

+ 72 - 0
src/main/java/com/fdkankan/contro/entity/RelocationBatchDetail.java

@@ -0,0 +1,72 @@
+package com.fdkankan.contro.entity;
+
+import com.baomidou.mybatisplus.annotation.*;
+import lombok.Getter;
+import lombok.Setter;
+
+import java.io.Serializable;
+import java.util.Date;
+
+/**
+ * <p>
+ * 
+ * </p>
+ *
+ * @author 
+ * @since 2025-09-09
+ */
+@Getter
+@Setter
+@TableName("t_relocation_batch_detail")
+public class RelocationBatchDetail implements Serializable {
+
+    private static final long serialVersionUID = 1L;
+
+    @TableId(value = "id", type = IdType.AUTO)
+    private Long id;
+
+    @TableField("batch_id")
+    private Long batchId;
+
+    /**
+     * 重定位场景码
+     */
+    @TableField("num")
+    private String num;
+
+    /**
+     * 全景图场景码
+     */
+    @TableField("pan_num")
+    private String panNum;
+
+    /**
+     * 图片key
+     */
+    @TableField("img_key")
+    private String imgKey;
+
+    /**
+     * 图片本地存储名称
+     */
+    @TableField("file_name")
+    private String fileName;
+
+    /**
+     * 图片 bucket
+     */
+    @TableField("bucket")
+    private String bucket;
+
+    @TableField("create_time")
+    private Date createTime;
+
+    @TableField("update_time")
+    private Date updateTime;
+
+    @TableField("rec_status")
+    @TableLogic(value = "A", delval = "I")
+    private String recStatus;
+
+
+}

+ 55 - 0
src/main/java/com/fdkankan/contro/entity/RelocationInit.java

@@ -0,0 +1,55 @@
+package com.fdkankan.contro.entity;
+
+import com.baomidou.mybatisplus.annotation.*;
+import lombok.Getter;
+import lombok.Setter;
+
+import java.io.Serializable;
+import java.util.Date;
+
+/**
+ * <p>
+ * 
+ * </p>
+ *
+ * @author 
+ * @since 2025-09-09
+ */
+@Getter
+@Setter
+@TableName("t_relocation_init")
+public class RelocationInit implements Serializable {
+
+    private static final long serialVersionUID = 1L;
+
+    @TableId(value = "id", type = IdType.AUTO)
+    private Long id;
+
+    @TableField("num")
+    private String num;
+
+    @TableField("pan_num")
+    private String panNum;
+
+    /**
+     * 0-等待推送,1-已推送
+     */
+    @TableField("status")
+    private Integer status;
+
+    @TableField("create_time")
+    private Date createTime;
+
+    @TableField("update_time")
+    private Date updateTime;
+
+    @TableField("rec_status")
+    @TableLogic(value = "A", delval = "I")
+    private String recStatus;
+
+    @TableField("unicode")
+    private String unicode;
+
+
+
+}

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

@@ -134,4 +134,11 @@ public class ScenePlus implements Serializable {
     @TableField("has_floorplan_ai")
     private Integer hasFloorplanAi;
 
+    /**
+     * 是否有禾赛
+     */
+    @TableField("has_hesai_data")
+    private Integer hasHesaiData;
+
+
 }

+ 6 - 0
src/main/java/com/fdkankan/contro/entity/ScenePro.java

@@ -232,4 +232,10 @@ public class ScenePro implements Serializable {
      */
     @TableField("is_obj")
     private Integer isObj;
+
+    /**
+     * 场景名称
+     */
+    @TableField("laser_title")
+    private String laserTitle;
 }

+ 16 - 1
src/main/java/com/fdkankan/contro/enums/CameraTypeEnum.java

@@ -1,5 +1,7 @@
 package com.fdkankan.contro.enums;
 
+import com.fdkankan.common.constant.FileBizType;
+
 import java.util.HashMap;
 import java.util.Map;
 
@@ -10,7 +12,8 @@ public enum CameraTypeEnum {
     ZHIHOUSE_REDHOUSE(5,"KK-","4DKKLITE_","指房宝小红屋相机"),
     DOUBLE_EYE_TURN(9,"KJ-","4DKKLITE_","双目转台"),
     LASER_TURN(10,"SS-","4DKKLA_","激光转台"),
-    LASER_SG(11,"SG-","4DSG_","深光");
+    LASER_SG(11,"SG-","4DSG_","深光"),
+    LASER_SX(12,"SX-","4DSX_","深巡");
 
 
     private int type;
@@ -48,4 +51,16 @@ public enum CameraTypeEnum {
         return "";
     }
 
+    public static CameraTypeEnum get(Integer type){
+        CameraTypeEnum[] values = CameraTypeEnum.values();
+        Integer enumValue = null;
+        for(CameraTypeEnum eachValue : values){
+            enumValue = eachValue.type;
+            if(enumValue.equals(type)){
+                return eachValue;
+            }
+        }
+        return null;
+    }
+
 }

+ 1 - 1
src/main/java/com/fdkankan/contro/generate/AutoGenerate.java

@@ -17,7 +17,7 @@ public class AutoGenerate {
         String path =System.getProperty("user.dir");
 
         generate(path,"contro", getTables(new String[]{
-                "t_app_camera_fail_log"
+                "t_relocation_init"
         }));
 
 //        generate(path,"goods", getTables(new String[]{

+ 18 - 0
src/main/java/com/fdkankan/contro/mapper/IRelocationBatchDetailMapper.java

@@ -0,0 +1,18 @@
+package com.fdkankan.contro.mapper;
+
+import com.fdkankan.contro.entity.RelocationBatchDetail;
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import org.apache.ibatis.annotations.Mapper;
+
+/**
+ * <p>
+ *  Mapper 接口
+ * </p>
+ *
+ * @author 
+ * @since 2025-09-09
+ */
+@Mapper
+public interface IRelocationBatchDetailMapper extends BaseMapper<RelocationBatchDetail> {
+
+}

+ 18 - 0
src/main/java/com/fdkankan/contro/mapper/IRelocationBatchMapper.java

@@ -0,0 +1,18 @@
+package com.fdkankan.contro.mapper;
+
+import com.fdkankan.contro.entity.RelocationBatch;
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import org.apache.ibatis.annotations.Mapper;
+
+/**
+ * <p>
+ * 重定位批次表 Mapper 接口
+ * </p>
+ *
+ * @author 
+ * @since 2025-09-09
+ */
+@Mapper
+public interface IRelocationBatchMapper extends BaseMapper<RelocationBatch> {
+
+}

+ 18 - 0
src/main/java/com/fdkankan/contro/mapper/IRelocationInitMapper.java

@@ -0,0 +1,18 @@
+package com.fdkankan.contro.mapper;
+
+import com.fdkankan.contro.entity.RelocationInit;
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import org.apache.ibatis.annotations.Mapper;
+
+/**
+ * <p>
+ *  Mapper 接口
+ * </p>
+ *
+ * @author 
+ * @since 2025-09-09
+ */
+@Mapper
+public interface IRelocationInitMapper extends BaseMapper<RelocationInit> {
+
+}

+ 0 - 1
src/main/java/com/fdkankan/contro/mq/listener/BuildIntermitSceneListener.java

@@ -1,7 +1,6 @@
 package com.fdkankan.contro.mq.listener;
 
 import com.fdkankan.contro.mq.service.impl.BuildIntermitSceneServiceImpl;
-import com.fdkankan.contro.mq.service.impl.BuildSceneServiceImpl;
 import com.rabbitmq.client.Channel;
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.amqp.core.Message;

+ 169 - 0
src/main/java/com/fdkankan/contro/mq/listener/BuildSxRelocationListener.java

@@ -0,0 +1,169 @@
+package com.fdkankan.contro.mq.listener;
+
+import cn.hutool.core.collection.CollUtil;
+import cn.hutool.core.exceptions.ExceptionUtil;
+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.fdkankan.common.constant.CommonOperStatus;
+import com.fdkankan.contro.entity.RelocationBatch;
+import com.fdkankan.contro.entity.RelocationBatchDetail;
+import com.fdkankan.contro.mq.service.impl.BuildSxRelocationServiceImpl;
+import com.fdkankan.contro.service.ICommonService;
+import com.fdkankan.contro.service.IRelocationBatchDetailService;
+import com.fdkankan.contro.service.IRelocationBatchService;
+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 java.nio.charset.StandardCharsets;
+import java.util.List;
+import java.util.stream.Collectors;
+
+@Slf4j
+@Component
+public class BuildSxRelocationListener {
+
+    @Value("${queue.modeling.relocation.relocation-pre:sx-relocation-pre}")
+    private String queueModelingPre;
+    @Value("${queue.modeling.relocation.relocation-post:sx-relocation-post}")
+    private String queueModelingPost;
+
+    @Autowired
+    private BuildSxRelocationServiceImpl buildSceneService;
+    @Autowired
+    private ISceneBuildProcessLogService sceneBuildProcessLogService;
+    @Autowired
+    private ICommonService commonService;
+    @Autowired
+    private IRelocationBatchService relocationBatchService;
+    @Autowired
+    private IRelocationBatchDetailService relocationBatchDetailService;
+
+
+    /**
+     * 场景计算前置资源准备处理
+     * @param channel
+     * @param message
+     * @throws Exception
+     */
+    @RabbitListener(
+            queuesToDeclare = @Queue("${queue.modeling.relocation.relocation-push:sx-relocation-push}"),
+            concurrency = "5"
+    )
+    public void push(Channel channel, Message message) throws Exception {
+        String messageId = message.getMessageProperties().getMessageId();
+        String msg = new String(message.getBody(), StandardCharsets.UTF_8);
+        JSONObject jsonObject = JSON.parseObject(msg);
+        log.info("开始接受重定位请求,id:{},消息体:{}", messageId, jsonObject);
+        String sxNum = jsonObject.getString("sxNum");
+        RelocationBatch relocationBatch = new RelocationBatch();
+        relocationBatch.setNum(sxNum);
+        relocationBatchService.save(relocationBatch);
+        JSONArray imgs = jsonObject.getJSONArray("imgs");
+        List<RelocationBatchDetail> detailList = imgs.stream().map(v -> {
+            JSONObject img = (JSONObject) v;
+            RelocationBatchDetail detail = new RelocationBatchDetail();
+            detail.setBatchId(relocationBatch.getId());
+            detail.setNum(sxNum);
+            detail.setPanNum(img.getString("num"));
+            detail.setBucket(img.getString("bucket"));
+            detail.setImgKey(img.getString("key"));
+            detail.setFileName(img.getString("fileName"));
+            return detail;
+        }).collect(Collectors.toList());
+        relocationBatchDetailService.saveBatch(detailList);
+
+
+        List<RelocationBatch> list = relocationBatchService.list(new LambdaQueryWrapper<RelocationBatch>().eq(RelocationBatch::getNum, sxNum).in(RelocationBatch::getStatus, 0, 1).lt(RelocationBatch::getId, relocationBatch.getId()));
+        boolean canBuild = true;
+        if(CollUtil.isNotEmpty(list)){
+            for (RelocationBatch batch : list) {
+                if(batch.getStatus() == 1){//如果已经有进入计算的重定位记录,则这次提交需要进入定时任务等待
+                    canBuild = false;
+                }
+                if(batch.getStatus() == 0){//如果前面有等待的,则丢弃等待的记录,因为最后一次推送是最全的
+                    relocationBatchService.removeById(batch);
+                }
+            }
+        }
+        if(canBuild){
+            relocationBatchService.relocationControlHandler(relocationBatch);
+        }
+
+        log.info("结束接受重定位请求,id:{}", messageId);
+        channel.basicAck(message.getMessageProperties().getDeliveryTag(), false);
+    }
+
+    /**
+     * 场景计算前置资源准备处理
+     * @param channel
+     * @param message
+     * @throws Exception
+     */
+    @RabbitListener(
+            queuesToDeclare = @Queue("${queue.modeling.relocation.relocation-pre:sx-relocation-pre}"),
+            concurrency = "5"
+    )
+    public void buildScenePreHandler(Channel channel, Message message) throws Exception {
+        String messageId = message.getMessageProperties().getMessageId();
+        String msg = new String(message.getBody(), StandardCharsets.UTF_8);
+        BuildSceneCallMessage buildSceneMessage = JSON.parseObject(msg, BuildSceneCallMessage.class);
+        String num = buildSceneMessage.getSceneNum();
+
+        log.info("开始准备重定位计算资源,队列名:{},id:{},消息体:{}", queueModelingPre, messageId, msg);
+        try {
+            //记录日志
+            sceneBuildProcessLogService.clearSceneBuildProcessLog(num, SceneBuildProcessType.PRE.code(), queueModelingPre, "relocation");
+            sceneBuildProcessLogService.saveSceneBuildProcessLog(num, SceneBuildProcessType.PRE.code(), queueModelingPre, CommonOperStatus.WAITING.code(), null, "relocation");
+            buildSceneService.buildScenePre(buildSceneMessage);
+            commonService.saveMqSendLog(num, buildSceneMessage, 0);
+            sceneBuildProcessLogService.saveSceneBuildProcessLog(num, SceneBuildProcessType.PRE.code(), queueModelingPre, CommonOperStatus.SUCCESS.code(), null,"relocation");
+        }catch (Exception e){
+            log.error("重定位计算前置处理出错,num=" + num, e);
+            sceneBuildProcessLogService.saveSceneBuildProcessLog(num, SceneBuildProcessType.PRE.code(), queueModelingPre, CommonOperStatus.FAILD.code(), ExceptionUtil.stacktraceToString(e, 3000), "relocation");
+        }
+        log.info("准备重定位计算资源完成,队列名:{},id:{},消息体:{}", queueModelingPre, messageId, msg);
+        channel.basicAck(message.getMessageProperties().getDeliveryTag(), false);
+    }
+
+    /**
+     * 场景计算后置结果处理
+     * @param channel
+     * @param message
+     * @throws Exception
+     */
+    @RabbitListener(
+            queuesToDeclare = @Queue("${queue.modeling.relocation.relocation-post:sx-relocation-post}"),
+            concurrency = "5"
+    )
+    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("场景重定位计算完成,开始处理计算结果,队列名:{},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, "relocation");
+            sceneBuildProcessLogService.saveSceneBuildProcessLog(num, SceneBuildProcessType.POST.code(), queueModelingPost, CommonOperStatus.WAITING.code(), null, "relocation");
+            buildSceneService.buildScenePost(buildSceneMessage);
+            sceneBuildProcessLogService.saveSceneBuildProcessLog(num, SceneBuildProcessType.POST.code(), queueModelingPost, CommonOperStatus.SUCCESS.code(), null, "relocation");
+        }catch (Exception e){
+            log.error("场景重定位计算结果处理出错,num=" + num, e);
+            sceneBuildProcessLogService.saveSceneBuildProcessLog(num, SceneBuildProcessType.POST.code(), queueModelingPost, CommonOperStatus.FAILD.code(), ExceptionUtil.stacktraceToString(e, 3000), "e57");
+        }
+        log.info("场景重定位计算结果处理完成,队列名:{},id:{},消息体:{}", queueModelingPost, messageId, msg);
+        channel.basicAck(message.getMessageProperties().getDeliveryTag(), false);
+    }
+}

+ 16 - 0
src/main/java/com/fdkankan/contro/mq/listener/UpdateSceneStatusListener.java

@@ -3,8 +3,14 @@ package com.fdkankan.contro.mq.listener;
 import cn.hutool.core.io.FileUtil;
 import com.alibaba.fastjson.JSON;
 import com.alibaba.fastjson.JSONObject;
+import com.fdkankan.common.constant.SceneSource;
+import com.fdkankan.common.constant.SceneStatus;
 import com.fdkankan.common.util.FileUtils;
+import com.fdkankan.contro.entity.ScenePlus;
+import com.fdkankan.contro.entity.ScenePlusExt;
 import com.fdkankan.contro.service.ICommonService;
+import com.fdkankan.contro.service.IScenePlusExtService;
+import com.fdkankan.contro.service.IScenePlusService;
 import com.fdkankan.fyun.face.FYunFileServiceInterface;
 import com.fdkankan.model.constants.ConstantFilePath;
 import com.fdkankan.model.constants.UploadFilePath;
@@ -28,6 +34,10 @@ public class UpdateSceneStatusListener {
     private FYunFileServiceInterface fYunFileService;
     @Autowired
     private ICommonService commonService;
+    @Autowired
+    private IScenePlusService scenePlusService;
+    @Autowired
+    private IScenePlusExtService scenePlusExtService;
 
     /**
      * 更新场景status.json状态
@@ -54,6 +64,12 @@ public class UpdateSceneStatusListener {
             if(status == 1){
                 commonService.sendEmail(num, "standar");
             }
+            ScenePlus scenePlus = scenePlusService.getScenePlusByNum(num);
+            if(scenePlus.getSceneSource() == SceneSource.QJKK.code()){
+                scenePlus.setSceneStatus(status == 1 ? SceneStatus.NO_DISPLAY.code() : status);
+                scenePlus.setUpdateTime(null);
+                scenePlusService.updateById(scenePlus);
+            }
         }catch (Exception e){
             log.error("更新场景的的status.json状态, content:{}", msg, e);
         }finally {

+ 14 - 11
src/main/java/com/fdkankan/contro/mq/service/impl/BuildE57SceneServiceImpl.java

@@ -1,18 +1,21 @@
 package com.fdkankan.contro.mq.service.impl;
 
 import cn.hutool.core.collection.CollUtil;
-import cn.hutool.core.io.FileUtil;
 import cn.hutool.core.util.ZipUtil;
 import com.alibaba.fastjson.JSON;
 import com.fdkankan.common.constant.CommonSuccessStatus;
 import com.fdkankan.contro.entity.ScenePlus;
 import com.fdkankan.contro.entity.ScenePlusExt;
 import com.fdkankan.contro.mq.service.IBuildSceneService;
-import com.fdkankan.contro.service.*;
+import com.fdkankan.contro.service.IBuildSceneDTService;
+import com.fdkankan.contro.service.IBuildService;
+import com.fdkankan.contro.service.IScenePlusExtService;
+import com.fdkankan.contro.service.IScenePlusService;
 import com.fdkankan.fyun.config.FYunFileConfig;
 import com.fdkankan.fyun.face.FYunFileServiceInterface;
 import com.fdkankan.model.constants.ConstantFilePath;
 import com.fdkankan.model.constants.UploadFilePath;
+import com.fdkankan.model.utils.CreateObjUtil;
 import com.fdkankan.rabbitmq.bean.BuildSceneCallMessage;
 import com.fdkankan.rabbitmq.bean.BuildSceneResultMqMessage;
 import com.fdkankan.rabbitmq.util.RabbitMqProducer;
@@ -66,11 +69,7 @@ public class BuildE57SceneServiceImpl implements IBuildSceneService {
     @Autowired
     private IBuildSceneDTService buildSceneDTService;
     @Autowired
-    private ICommonService commonService;
-    @Autowired
-    private ISceneColdStorageService sceneColdStorageService;
-    @Autowired
-    private IntermitSceneService intermitSceneService;
+    private IBuildService buildService;
 
     @Override
     public void buildScenePre(BuildSceneCallMessage message) throws Exception{
@@ -91,6 +90,12 @@ public class BuildE57SceneServiceImpl implements IBuildSceneService {
             message.setResultReceiverMqName(queueModelingPost);
             message.setBizType("e57");
 
+            //写入算法参数文件
+            Map<String, String> dataMap = new HashMap<>();
+            dataMap.put("splitType", "SPLIT_V27");
+            dataMap.put("skyboxType", "SKYBOX_V11");
+            buildService.writeDataJson(message, null, dataMap, null);
+
             log.info("e57计算资源准备结束,场景码:{}", message.getSceneNum());
 
         }catch (Exception e){
@@ -168,10 +173,8 @@ public class BuildE57SceneServiceImpl implements IBuildSceneService {
             laserMqContent.put("status", CommonSuccessStatus.SUCCESS.code());
             mqProducer.sendByWorkQueue(queueE57ModelingDone, laserMqContent);
 
-            try {
-                FileUtil.del(path);
-            }catch (Exception e){
-                log.error("删除计算目录失败,path:{}", path);
+            if(CollUtil.isEmpty(notDeleteNasNumList) || !notDeleteNasNumList.contains(num)){
+                CreateObjUtil.deleteFile(path.replace(ConstantFilePath.BUILD_MODEL_PATH, "/"));
             }
 
             log.info("e57场景计算结果处理结束,场景码:{}", num);

+ 29 - 19
src/main/java/com/fdkankan/contro/mq/service/impl/BuildIntermitSceneServiceImpl.java

@@ -8,6 +8,7 @@ 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.entity.RelocationInit;
 import com.fdkankan.contro.entity.ScenePlus;
 import com.fdkankan.contro.entity.ScenePlusExt;
 import com.fdkankan.contro.mq.service.IBuildSceneService;
@@ -23,7 +24,6 @@ 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.StringUtils;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.beans.factory.annotation.Value;
 import org.springframework.cloud.context.config.annotation.RefreshScope;
@@ -76,6 +76,10 @@ public class BuildIntermitSceneServiceImpl implements IBuildSceneService {
     private ISceneColdStorageService sceneColdStorageService;
     @Autowired
     private IntermitSceneService intermitSceneService;
+    @Autowired
+    private IBuildService buildService;
+    @Autowired
+    private IRelocationInitService relocationInitService;
 
     @Override
     public void buildScenePre(BuildSceneCallMessage message) throws Exception{
@@ -113,6 +117,9 @@ public class BuildIntermitSceneServiceImpl implements IBuildSceneService {
             message.setResultReceiverMqName(queueModelingPost);
             message.setBizType("intermit");
 
+            JSONObject fdageData = commonService.getFdageData(message.getPath() + File.separator + "capture" + File.separator + "data.fdage");
+            buildService.writeDataJson(message, fdageData, null, null);
+
             log.info("场景计算资源准备结束,场景码:{}", message.getSceneNum());
 
         }catch (Exception e){
@@ -150,7 +157,7 @@ public class BuildIntermitSceneServiceImpl implements IBuildSceneService {
             fYunFileService.uploadFile(path + File.separator + "console.log", buildLogPath + "console.log");
             log.info("计算日志上传完成");
 
-            JSONObject fdageData = getFdageData(path + File.separator + "capture" +File.separator+"data.fdage");
+            JSONObject fdageData = commonService.getFdageData(path + File.separator + "capture" +File.separator+"data.fdage");
 
             if (!message.getBuildSuccess()) {
                 log.error("建模失败,修改状态为失败状态");
@@ -173,7 +180,7 @@ public class BuildIntermitSceneServiceImpl implements IBuildSceneService {
 
             scenePlus.setPayStatus(PayStatus.PAY.code());
             scenePlus.setUpdateTime(new Date());
-            scenePlus.setSceneStatus(SceneStatus.NO_DISPLAY.code());
+//            scenePlus.setSceneStatus(SceneStatus.NO_DISPLAY.code());
 
             Integer videoVersion = fdageData.getInteger("videoVersion");
             //读取计算结果文件生成videosJson
@@ -182,6 +189,11 @@ public class BuildIntermitSceneServiceImpl implements IBuildSceneService {
             ScenePlusExt scenePlusExt = scenePlusExtService.getScenePlusExtByPlusId(scenePlus.getId());
 
             log.info("开始上传场景计算结果数据,num:{}", sceneCode);
+            //上传结算结果之前需要删除oss上的结果数据
+            String panoramaKey = String.format(UploadFilePath.IMG_VIEW_PATH, sceneCode) + "panoramas";
+            if(fYunFileService.fileExist(panoramaKey)){
+                fYunFileService.deleteFolder(panoramaKey);
+            }
             //上传文件
             fYunFileService.uploadMulFiles(uploadFiles);
 
@@ -189,7 +201,7 @@ public class BuildIntermitSceneServiceImpl implements IBuildSceneService {
             Long space = commonService.getSpace(sceneCode);
 
             //写入数据库
-            this.updateDbPlus(scenePlus.getSceneSource(), space, videosJson.toJSONString(), message.getComputeTime(),false,scenePlusExt);
+            this.updateDbPlus(scenePlus.getSceneSource(), space, videosJson.toJSONString(), message.getComputeTime(),scenePlusExt);
 
             Object[] editInfoArr = commonService.updateEditInfo(scenePlus);
 
@@ -212,6 +224,17 @@ public class BuildIntermitSceneServiceImpl implements IBuildSceneService {
             //推送到全景看看
             intermitSceneService.sendMq(sceneCode, fdageData, CommonSuccessStatus.SUCCESS.code());
 
+            //判断是否有重定位关系,如果有,推送到激光系统去做初始化处理
+            String sxUuid = fdageData.getString("parentScene");
+            ScenePlus sxScenePlus = scenePlusService.getByFileId(sxUuid);
+            RelocationInit relocationInit = new RelocationInit();
+            relocationInit.setUnicode(sxUuid);
+            if(Objects.nonNull(sxScenePlus)){
+                relocationInit.setNum(sxScenePlus.getNum());
+            }
+            relocationInit.setPanNum(sceneCode);
+            relocationInitService.save(relocationInit);
+
             log.info("场景计算结果处理结束,场景码:{}", sceneCode);
 
         }catch (Exception e){
@@ -252,26 +275,14 @@ public class BuildIntermitSceneServiceImpl implements IBuildSceneService {
         return map;
     }
 
-    private JSONObject getFdageData(String dataFdagePath) {
-        log.info("dataFdagePath 文件路径 :{}", dataFdagePath);
-        String data = FileUtils.readFile(dataFdagePath);
-        //获取data.fdage的内容
-        JSONObject dataJson = new JSONObject();
-        if(data!=null){
-            dataJson = JSONObject.parseObject(data);
-        }
-        return dataJson;
-    }
-
     private void uploadStatusJson(ScenePlus scenePlus, ScenePlusExt scenePlusExt){
         String num = scenePlus.getNum();
         String dataViewPath = String.format(UploadFilePath.DATA_VIEW_PATH, num);
 
-        Integer status = 1;
         // 上传status JSON.
         JSONObject statusJson = new JSONObject();
         //临时将-2改成1,app还没完全更新
-        statusJson.put("status", status);
+        statusJson.put("status", scenePlus.getSceneStatus());
         statusJson.put("webSite", scenePlusExt.getWebSite());
         statusJson.put("sceneNum", num);
         statusJson.put("thumb", scenePlusExt.getThumb());
@@ -282,13 +293,12 @@ public class BuildIntermitSceneServiceImpl implements IBuildSceneService {
         fYunFileService.uploadFile(statusJson.toJSONString().getBytes(StandardCharsets.UTF_8), dataViewPath + "status.json");
     }
 
-    private void updateDbPlus(int sceneSource,Long space,String videosJson, Long computeTime,boolean isObj,ScenePlusExt scenePlusExt){
+    private void updateDbPlus(int sceneSource,Long space,String videosJson, Long computeTime,ScenePlusExt scenePlusExt){
 
         scenePlusExt.setSpace(space);
         scenePlusExt.setComputeTime(computeTime);
         scenePlusExt.setAlgorithmTime(new Date());
         scenePlusExt.setVideos(videosJson);
-        scenePlusExt.setIsObj(isObj ? 1 : 0);
 
         if(ModelTypeEnums.TILE_CODE.equals(modelType)){
             scenePlusExt.setSceneScheme(3);

+ 7 - 7
src/main/java/com/fdkankan/contro/mq/service/impl/BuildLiguangServiceImpl.java

@@ -3,7 +3,6 @@ package com.fdkankan.contro.mq.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 cn.hutool.extra.qrcode.QrCodeUtil;
 import cn.hutool.extra.qrcode.QrConfig;
 import cn.hutool.http.ContentType;
@@ -14,7 +13,6 @@ 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;
@@ -129,6 +127,8 @@ public class BuildLiguangServiceImpl implements IBuildSceneService {
     private ISceneBuildProcessLogService sceneBuildProcessLogService;
     @Autowired
     private ISceneColdStorageService sceneColdStorageService;
+    @Autowired
+    private IBuildService buildService;
 
 
     @Override
@@ -160,9 +160,11 @@ public class BuildLiguangServiceImpl implements IBuildSceneService {
 
 
             message.getBuildContext().put("cameraType",message.getCameraType());
-
             message.setBizType("standard");
 
+            JSONObject fdageData = commonService.getFdageData(message.getPath() + File.separator + "capture" + File.separator + "data.fdage");
+            buildService.writeDataJson(message, fdageData, null, null);
+
             log.info("场景计算资源准备结束,场景码:{}", message.getSceneNum());
 
         }catch (Exception e){
@@ -226,7 +228,6 @@ public class BuildLiguangServiceImpl implements IBuildSceneService {
             JSONObject videosJson = commonService.getVideosJson(path, videoVersion, sceneCode, cameraType);
 
             ScenePlusExt scenePlusExt = scenePlusExtService.getScenePlusExtByPlusId(scenePlus.getId());
-            boolean isObj = fdageData.containsKey("exportMeshObj") && fdageData.getIntValue("exportMeshObj") == 1;
 
             //上传全景图俯视图
             this.uploadFloorCad(path, sceneCode, uploadFiles);
@@ -274,7 +275,7 @@ public class BuildLiguangServiceImpl implements IBuildSceneService {
             Long space = commonService.getSpace(sceneCode);
 
             //写入数据库
-            this.updateDbPlus(scenePlus.getSceneSource(), space, videosJson.toJSONString(), message.getComputeTime(),isObj,scenePlusExt);
+            this.updateDbPlus(scenePlus.getSceneSource(), space, videosJson.toJSONString(), message.getComputeTime(),scenePlusExt);
 
             Object[] editInfoArr = commonService.updateEditInfo(scenePlus);
             SceneEditInfo sceneEditInfo = (SceneEditInfo)editInfoArr[0];
@@ -478,13 +479,12 @@ public class BuildLiguangServiceImpl implements IBuildSceneService {
         }
     }
 
-    private void updateDbPlus(int sceneSource,Long space,String videosJson, Long computeTime,boolean isObj,ScenePlusExt scenePlusExt){
+    private void updateDbPlus(int sceneSource,Long space,String videosJson, Long computeTime,ScenePlusExt scenePlusExt){
 
         scenePlusExt.setSpace(space);
         scenePlusExt.setComputeTime(computeTime);
         scenePlusExt.setAlgorithmTime(new Date());
         scenePlusExt.setVideos(videosJson);
-        scenePlusExt.setIsObj(isObj ? 1 : 0);
 
         if(ModelTypeEnums.TILE_CODE.equals(modelType)){
             scenePlusExt.setSceneScheme(3);

+ 7 - 1
src/main/java/com/fdkankan/contro/mq/service/impl/BuildObjServiceImpl.java

@@ -105,6 +105,8 @@ public class BuildObjServiceImpl implements IBuildSceneService {
     private ICameraDetailService cameraDetailService;
     @Autowired
     private ICompanyService companyService;
+    @Autowired
+    private IBuildService buildService;
 
     @Override
     public void buildScenePre(BuildSceneCallMessage message) throws Exception{
@@ -119,7 +121,6 @@ public class BuildObjServiceImpl implements IBuildSceneService {
             FileUtils.delAllFile(laserObjFilePath);
 
             //获取解压后的资源的data.fdage中的数据
-            File folderPath = new File(path);
             fYunFileService.downloadFile(ConstantFilePath.OSS_PREFIX + path.replace(ConstantFilePath.BUILD_MODEL_LASER_PATH, "") + "/data.fdage", laserObjFilePath + "/capture/data.fdage");
             JSONObject jsonObject = FileUtils.readJson(laserObjFilePath + File.separator + "capture" + File.separator + "data.fdage");
             if(ObjectUtils.isEmpty(jsonObject)){
@@ -147,6 +148,11 @@ public class BuildObjServiceImpl implements IBuildSceneService {
             message.setResultReceiverMqName(queueObjModelingPost);
             message.setBizType("obj");
 
+            JSONObject fdageData = commonService.getFdageData(laserObjFilePath + File.separator + "capture" + File.separator + "data.fdage");
+            Map<String, Object> dataExtras = new HashMap<>(1);
+            dataExtras.put("big_depthmap", true);
+            buildService.writeDataJson(message, fdageData, null, dataExtras);
+
             success = true;
 
             log.info("场景计算资源准备结束,场景码:{}", message.getSceneNum());

+ 39 - 9
src/main/java/com/fdkankan/contro/mq/service/impl/BuildReverseE57SceneServiceImpl.java

@@ -2,9 +2,7 @@ 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;
@@ -14,12 +12,10 @@ 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;
@@ -86,6 +82,8 @@ public class BuildReverseE57SceneServiceImpl implements IBuildSceneService {
     private IFdkkLaserService fdkkLaserService;
     @Autowired
     private ISceneEditControlsService sceneEditControlsService;
+    @Autowired
+    private IBuildService buildService;
 
     @Value("${main.url}")
     private String mainUrl;
@@ -93,7 +91,6 @@ public class BuildReverseE57SceneServiceImpl implements IBuildSceneService {
     public void buildScenePre(BuildSceneCallMessage message) throws Exception{
         String num = message.getSceneNum();
         Integer rebuild = (Integer)message.getExt().get("rebuild");
-        Boolean deleteExtras = (Boolean)message.getExt().get("deleteExtras");
         ScenePlus scenePlus = scenePlusService.getScenePlusByNum(num);
         ScenePlusExt scenePlusExt = scenePlusExtService.getScenePlusExtByPlusId(scenePlus.getId());
         try {
@@ -101,16 +98,12 @@ public class BuildReverseE57SceneServiceImpl implements IBuildSceneService {
             String homePath = SceneUtil.getHomePath(dataSource);
             message.setPath(dataSource);
             String homeKey = homePath + "input.e57";
-            String key = null;
             if(Objects.isNull(rebuild) || rebuild == CommonStatus.NO.code().intValue()){
                 String path = (String)message.getExt().get("path");
                 //复制原始资源到home目录
                 fYunFileService.copyFileInBucket(path, homeKey);
                 //删除临时文件
                 fYunFileService.deleteFile(path);
-                key = homeKey;
-            }else{
-                key = homeKey;
             }
 
             //删除点位校准数据
@@ -137,6 +130,19 @@ public class BuildReverseE57SceneServiceImpl implements IBuildSceneService {
             message.setResultReceiverMqName(queueModelingPost);
             message.setBizType("reverseE57");
 
+            String splitType = "SPLIT_V29";
+            String skyboxType = "SKYBOX_V11";
+            String otherType = (String)message.getExt().get("otherType");
+            Integer isObj = (Integer) message.getExt().get("isObj");
+            if(StrUtil.isNotEmpty(modelType) && ModelTypeEnums.TILE_CODE.equals(modelType)){
+                skyboxType = "SKYBOX_V15";
+            }
+            if(Objects.nonNull(isObj) && isObj == CommonStatus.YES.code().intValue()){
+                splitType = "SPLIT_V30";
+            }
+
+            this.createProjectAndDataFile(message.getPath(), num, splitType, skyboxType,otherType,null,null);
+
             log.info("上传e57计算资源准备结束,场景码:{}", message.getSceneNum());
 
         }catch (Exception e){
@@ -149,6 +155,26 @@ public class BuildReverseE57SceneServiceImpl implements IBuildSceneService {
         }
     }
 
+    public void createProjectAndDataFile(String path, String sceneNum, String splitType, String skyboxType, String otherType, Map<String, Object> projectExtras, Map<String, Object> dataExtras) {
+        JSONObject projectJson = new JSONObject();
+        if (!org.apache.commons.lang3.ObjectUtils.isEmpty(projectExtras)) {
+            projectJson.putAll(projectExtras);
+        }
+
+        projectJson.put("sceneNum", sceneNum);
+        FileUtils.writeFile(path + File.separator + "project.json", projectJson.toString());
+        JSONObject dataJson = new JSONObject();
+        if (!org.apache.commons.lang3.ObjectUtils.isEmpty(dataExtras)) {
+            dataJson.putAll(dataExtras);
+        }
+
+        dataJson.put("split_type", splitType);
+        dataJson.put("skybox_type", skyboxType);
+        dataJson.put("extras", (Object)null);
+        dataJson.put("other_type", otherType);
+        FileUtils.writeFile(path + File.separator + "data.json", dataJson.toString());
+    }
+
     private String getOssPath(String path) {
         String ossPath = ConstantFilePath.OSS_PREFIX
                 + path.replace(ConstantFilePath.BUILD_MODEL_PATH, "")
@@ -294,6 +320,10 @@ public class BuildReverseE57SceneServiceImpl implements IBuildSceneService {
             scenePlusService.updateById(scenePlus);
             scenePlusExtService.updateById(scenePlusExt);
 
+            if(CollUtil.isEmpty(notDeleteNasNumList) || !notDeleteNasNumList.contains(sceneCode)){
+                CreateObjUtil.deleteFile(path.replace(ConstantFilePath.BUILD_MODEL_PATH, "/"));
+            }
+
             log.info("场景计算结果处理结束,场景码:{}", sceneCode);
 
         }catch (Exception e){

+ 18 - 4
src/main/java/com/fdkankan/contro/mq/service/impl/BuildSceneServiceImpl.java

@@ -132,6 +132,8 @@ public class BuildSceneServiceImpl implements IBuildSceneService {
     private IWbService wbService;
     @Autowired
     private IAiService aiService;
+    @Autowired
+    private IBuildService buildService;
 
 
     @Override
@@ -206,10 +208,17 @@ public class BuildSceneServiceImpl implements IBuildSceneService {
 
             message.setBizType("standard");
 
+            //写入算法参数文件
+            buildService.writeDataJson(message, fdageJson, null, null);
+
             log.info("场景计算资源准备结束,场景码:{}", message.getSceneNum());
 
         }catch (Exception e){
             log.error("场景计算前置处理出错,num"+num, e);
+
+            //计算失败通知激光系统修改状态
+            fdkkLaserService.updateStatus(num, 1);
+
             buildSceneDTService.handBaseFail("场景计算资源准备异常!", message.getPath(), message.getSceneNum(), "计算控制服务器");
             throw e;
         }
@@ -251,6 +260,9 @@ public class BuildSceneServiceImpl implements IBuildSceneService {
 
                 wbService.sendMq(sceneCode, CommonSuccessStatus.FAIL.code());
 
+                //计算失败通知激光系统修改状态
+                fdkkLaserService.updateStatus(sceneCode, 1);
+
                 // 发送钉钉消息,计算失败
                 buildSceneDTService.handModelFail("计算失败", message.getPath(), sceneCode, message.getHostName());
                 return;
@@ -271,7 +283,6 @@ public class BuildSceneServiceImpl implements IBuildSceneService {
             JSONObject videosJson = commonService.getVideosJson(path, videoVersion, sceneCode, cameraType);
 
             ScenePlusExt scenePlusExt = scenePlusExtService.getScenePlusExtByPlusId(scenePlus.getId());
-            boolean isObj = fdageData.containsKey("exportMeshObj") && fdageData.getIntValue("exportMeshObj") == 1;
 
             //上传全景图俯视图
             this.uploadFloorCad(path, sceneCode, uploadFiles);
@@ -333,7 +344,7 @@ public class BuildSceneServiceImpl implements IBuildSceneService {
             aiService.detectScenePano(scenePlus, scenePlusExt, path);
 
             //写入数据库
-            this.updateDbPlus(scenePlus, scenePlusExt, space, videosJson.toJSONString(), message.getComputeTime(),isObj);
+            this.updateDbPlus(scenePlus, scenePlusExt, space, videosJson.toJSONString(), message.getComputeTime());
 
             Object[] editInfoArr = commonService.updateEditInfo(scenePlus);
             SceneEditInfo sceneEditInfo = (SceneEditInfo)editInfoArr[0];
@@ -410,6 +421,10 @@ public class BuildSceneServiceImpl implements IBuildSceneService {
 
         }catch (Exception e){
             log.error("场景计算结果处理出错,num"+sceneCode, e);
+
+            //计算失败通知激光系统修改状态
+            fdkkLaserService.updateStatus(sceneCode, 1);
+
             buildSceneDTService.handBaseFail("场景计算结果处理出错!", message.getPath(), sceneCode, "计算控制服务器");
             throw e;
         } finally {
@@ -572,13 +587,12 @@ public class BuildSceneServiceImpl implements IBuildSceneService {
         }
     }
 
-    private void updateDbPlus(ScenePlus scenePlus,ScenePlusExt scenePlusExt, Long space,String videosJson, Long computeTime,boolean isObj){
+    private void updateDbPlus(ScenePlus scenePlus,ScenePlusExt scenePlusExt, Long space,String videosJson, Long computeTime){
 
         scenePlusExt.setSpace(space);
         scenePlusExt.setComputeTime(computeTime);
         scenePlusExt.setAlgorithmTime(new Date());
         scenePlusExt.setVideos(videosJson);
-        scenePlusExt.setIsObj(isObj ? 1 : 0);
 
         if(ModelTypeEnums.TILE_CODE.equals(modelType)){
             scenePlusExt.setSceneScheme(3);

+ 321 - 0
src/main/java/com/fdkankan/contro/mq/service/impl/BuildSxRelocationServiceImpl.java

@@ -0,0 +1,321 @@
+package com.fdkankan.contro.mq.service.impl;
+
+import cn.hutool.core.io.FileUtil;
+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.entity.RelocationBatch;
+import com.fdkankan.contro.entity.RelocationBatchDetail;
+import com.fdkankan.contro.entity.ScenePlus;
+import com.fdkankan.contro.entity.ScenePlusExt;
+import com.fdkankan.contro.mq.service.IBuildSceneService;
+import com.fdkankan.contro.service.*;
+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.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.nio.charset.StandardCharsets;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.stream.Collectors;
+
+
+/**
+ * <p>
+ * TODO
+ * </p>
+ *
+ * @author dengsixing
+ * @since 2022/4/20
+ **/
+@Slf4j
+@Service
+@RefreshScope
+public class BuildSxRelocationServiceImpl implements IBuildSceneService {
+
+    @Value("${queue.modeling.sx-relocation-post:sx-relocation-post}")
+    private String queueModelingPost;
+    @Value("${model.type:#{null}}")
+    private String modelType;
+    @Value("${env:gn}")
+    private String env;
+    @Autowired
+    private RabbitMqProducer mqProducer;
+    @Resource
+    private FYunFileServiceInterface fYunFileService;
+    @Autowired
+    private IScenePlusService scenePlusService;
+    @Autowired
+    private IScenePlusExtService scenePlusExtService;
+    @Autowired
+    private IBuildSceneDTService buildSceneDTService;
+    @Autowired
+    private ICommonService commonService;
+    @Autowired
+    private IBuildService buildService;
+    @Autowired
+    private IRelocationBatchDetailService relocationBatchDetailService;
+    @Autowired
+    private IRelocationBatchService relocationBatchService;
+
+    @Override
+    public void buildScenePre(BuildSceneCallMessage message) throws Exception{
+        String num = message.getSceneNum();
+        Long batchId = Long.valueOf(message.getExt().get("batchId").toString());
+        ScenePlus scenePlusByNum = scenePlusService.getScenePlusByNum(num);
+        try {
+            //重新计算时需要删除文件夹,否知使用缓存
+            if(new File(message.getPath() + File.separator + "results").exists()){
+                FileUtils.deleteDirectory(message.getPath() + File.separator + "results");
+            }
+            //由于刘强说caches会影响计算结果,所以这里删除caches
+            if(new File(message.getPath() + File.separator + "caches").exists()){
+                FileUtils.deleteDirectory(message.getPath() + File.separator + "caches");
+            }
+
+            this.downLoadSource(message, message.getPath());
+
+            message.setResultReceiverMqName(queueModelingPost);
+            Map<String, Object> buildContext = new HashMap<>();
+            buildContext.put("sceneNum",message.getSceneNum());
+            message.setBuildContext(buildContext);
+
+            Map<String, String> dataMap = new HashMap<>();
+            dataMap.put("splitType", "SPLIT_V31");
+            dataMap.put("skyboxType", "SKYBOX_V6");
+            if(ModelTypeEnums.TILE_CODE.equals(modelType)){
+                dataMap.put("skyboxType", "SKYBOX_V14");
+            }
+            buildService.writeDataJson(message, new JSONObject(), dataMap, null);
+        }catch (Exception e){
+            scenePlusByNum.setSceneStatus(SceneStatus.FAILD.code());
+            scenePlusService.updateById(scenePlusByNum);
+            //修改重定位记录为退出计算
+            relocationBatchService.update(new LambdaUpdateWrapper<RelocationBatch>().eq(RelocationBatch::getId, batchId).set(RelocationBatch::getStatus, 2));
+            buildSceneDTService.handBaseFail("深巡场景重定位资源准备异常!", message.getPath(), message.getSceneNum(), "计算控制服务器");
+            throw e;
+        }
+    }
+
+    @Override
+    public void downLoadSource(BuildSceneCallMessage buildSceneMqMessage,String path){
+        String num = buildSceneMqMessage.getSceneNum();
+        Long batchId = Long.valueOf(buildSceneMqMessage.getExt().get("batchId").toString());
+        //下载深巡缓存数据
+        String extrasPath = path + File.separator + "extras";
+        fYunFileService.downloadFileByCommand(extrasPath, String.format(UploadFilePath.scene_result_data_path, num) + "pose/");
+        String imagesPath = extrasPath + File.separator + "images";
+        //下载图片
+        String queryPath = imagesPath + File.separator + "query";
+        List<RelocationBatchDetail> detailList = relocationBatchDetailService.listByBatchId(batchId);
+        detailList.stream().forEach(v->{
+            fYunFileService.downloadFile(v.getBucket(), v.getImgKey(), queryPath + File.separator + v.getFileName());
+        });
+        //生成query.json
+        List<String> imgNameList = FileUtil.listFileNames(queryPath);
+        List<JSONObject> filenames = imgNameList.stream().map(v -> {
+            JSONObject a = new JSONObject();
+            a.put("filename", v);
+            return a;
+        }).collect(Collectors.toList());
+        JSONObject query = new JSONObject();
+        query.put("query", filenames);
+        FileUtil.writeUtf8String(query.toJSONString(), extrasPath + File.separator + "query.json");
+    }
+
+    @Override
+    public void buildScenePost(BuildSceneResultMqMessage message) throws Exception {
+        String sceneCode = message.getBuildContext().get("sceneNum").toString();
+        Long batchId = Long.valueOf(message.getExt().get("batchId").toString());
+        String path = message.getPath();
+        Map<String, Object> downParams = new HashMap<>();
+        downParams.put("sceneCode", sceneCode);
+        downParams.put("path", path);
+        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("重定位计算报错,修改状态为失败状态");
+                scenePlusService.update(new LambdaUpdateWrapper<ScenePlus>()
+                        .set(ScenePlus::getSceneStatus, SceneStatus.FAILD.code())
+                        .eq(ScenePlus::getNum, sceneCode));
+
+                // 发送钉钉消息,计算失败
+                buildSceneDTService.handModelFail("深巡场景重定向计算失败", message.getPath(), sceneCode, message.getHostName());
+                return;
+            }
+            ScenePlus scenePlus = scenePlusService.getScenePlusByNum(sceneCode);
+            Map<String, String> uploadFiles = this.getUploadFiles(scenePlus,path);
+
+            scenePlus.setPayStatus(PayStatus.PAY.code());
+            scenePlus.setUpdateTime(new Date());
+            scenePlus.setSceneStatus(SceneStatus.NO_DISPLAY.code());
+
+            ScenePlusExt scenePlusExt = scenePlusExtService.getScenePlusExtByPlusId(scenePlus.getId());
+            log.info("开始上传场景计算结果数据,num:{}", sceneCode);
+            //上传文件
+            fYunFileService.uploadMulFiles(uploadFiles);
+
+            //上传caches/images
+            String  ossResultPath = String.format(UploadFilePath.scene_result_data_path, sceneCode);
+            String localCachesImagePath = path + "/caches/images/";
+            String ossCachesImagePath = ossResultPath + "caches/images/";
+            if(FileUtil.exist(localCachesImagePath)){
+                fYunFileService.uploadFileByCommand(localCachesImagePath, ossCachesImagePath);
+            }
+
+            //容量统计
+            Long space = commonService.getSpace(sceneCode);
+
+            Object[] editInfoArr = commonService.updateEditInfo(scenePlus);
+
+            //如果相机容量不足,需要把场景的paystatus改为容量不足状态
+            scenePlus.setPayStatus(commonService.getPayStatus(scenePlus.getCameraId(), space, new JSONObject()));
+
+            this.uploadStatusJson(scenePlus, scenePlusExt);
+
+            //目前重定位只能用看见的全景图去做重定位,所以这里固定给4k
+            scenePlusExt.setSceneResolution(SceneResolution.four_K.code());
+            scenePlusService.updateById(scenePlus);
+            scenePlusExtService.updateById(scenePlusExt);
+
+            //国际环境需要发邮件通知
+            if("eur".equals(env) &&
+                    !scenePlus.getSceneSource().equals(SceneSource.JG.code()) &&
+                    !scenePlus.getSceneSource().equals(SceneSource.SG.code())){
+                commonService.sendEmail(sceneCode, "relocation");
+            }
+
+            //发送消息到点云系统处理
+            downParams.put("status", CommonSuccessStatus.SUCCESS.code());
+            log.info("场景重定位计算结果处理结束,场景码:{}", sceneCode);
+
+        }catch (Exception e){
+            log.error("场景重定位计算结果处理出错,num"+sceneCode, e);
+            downParams.put("status", CommonSuccessStatus.FAIL.code());
+            buildSceneDTService.handBaseFail("场景重定位计算结果处理出错!", message.getPath(), sceneCode, "计算控制服务器");
+            throw e;
+        } finally {
+            //发送消息到激光系统做处理
+            mqProducer.sendByWorkQueue("sx-relocation-done", downParams);
+            //修改重定位记录为退出计算
+            relocationBatchService.update(new LambdaUpdateWrapper<RelocationBatch>().eq(RelocationBatch::getId, batchId).set(RelocationBatch::getStatus, 2));
+        }
+    }
+
+    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");
+        return map;
+    }
+
+    private void uploadStatusJson(ScenePlus scenePlus, ScenePlusExt scenePlusExt){
+        String num = scenePlus.getNum();
+        String dataViewPath = String.format(UploadFilePath.DATA_VIEW_PATH, num);
+
+        Integer status = 1;
+        // 上传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");
+    }
+}

+ 4 - 2
src/main/java/com/fdkankan/contro/mq/service/impl/BuildV3SceneServiceImpl.java

@@ -115,6 +115,8 @@ public class BuildV3SceneServiceImpl implements IBuildSceneService {
 
     @Autowired
     private ICompanyService companyService;
+    @Autowired
+    private IBuildService buildService;
 
     @Override
     public void buildScenePre(BuildSceneCallMessage message) {
@@ -159,11 +161,11 @@ public class BuildV3SceneServiceImpl implements IBuildSceneService {
             }
 
             message.getBuildContext().put("cameraType",message.getCameraType());
-
             message.setResultReceiverMqName(queueV3ModelingPost);
-
             message.setBizType("standard");
 
+            buildService.writeDataJson(message, fdageJson, null, null);
+
             log.info("场景计算资源准备结束,场景码:{}", message.getSceneNum());
 
         }catch (Exception e){

+ 26 - 3
src/main/java/com/fdkankan/contro/schedule/ScheduleJob.java

@@ -1,11 +1,10 @@
 package com.fdkankan.contro.schedule;
 
+import com.fdkankan.contro.service.IRelocationBatchService;
+import com.fdkankan.contro.service.IRelocationInitService;
 import com.fdkankan.contro.service.IScene3dNumService;
-import com.fdkankan.rabbitmq.util.RabbitMqProducer;
-import com.fdkankan.rubbersheeting.ScalingService;
 import lombok.extern.log4j.Log4j2;
 import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.beans.factory.annotation.Value;
 import org.springframework.scheduling.annotation.Scheduled;
 import org.springframework.stereotype.Component;
 
@@ -15,6 +14,10 @@ public class ScheduleJob {
 
     @Autowired
     private IScene3dNumService scene3dNumService;
+    @Autowired
+    private IRelocationBatchService relocationBatchService;
+    @Autowired
+    private IRelocationInitService relocationInitService;
 
 
     /**
@@ -24,4 +27,24 @@ public class ScheduleJob {
     public void generateSceneNum() {
         scene3dNumService.generateSceneNumHandler();
     }
+
+    /**
+     * 重定位调度
+     */
+    @Scheduled(fixedDelay = 5*60*1000, initialDelay = 1000)
+    public void relocationControl() {
+        log.info("重定位调度开始");
+        relocationBatchService.relocationControl();
+        log.info("重定位调度结束");
+    }
+
+    /**
+     * 重定位调度
+     */
+    @Scheduled(fixedDelay = 5*60*1000, initialDelay = 1000)
+    public void relocationInit() {
+        log.info("重定位初始化调度开始");
+        relocationInitService.relocationInit();
+        log.info("重定位初始化调度结束");
+    }
 }

+ 14 - 0
src/main/java/com/fdkankan/contro/service/IBuildService.java

@@ -0,0 +1,14 @@
+package com.fdkankan.contro.service;
+
+import com.alibaba.fastjson.JSONObject;
+import com.fdkankan.rabbitmq.bean.BuildSceneCallMessage;
+
+import java.util.Map;
+
+public interface IBuildService {
+
+    Map<String, String> getTypeString(String cameraType, String algorithm, String resolution, JSONObject fdageData);
+
+    void writeDataJson(BuildSceneCallMessage message, JSONObject dataFdage, Map<String, String> dataMap, Map<String, Object> dataExtras);
+
+}

+ 3 - 1
src/main/java/com/fdkankan/contro/service/ICameraTypeService.java

@@ -8,11 +8,13 @@ import com.baomidou.mybatisplus.extension.service.IService;
  *  服务类
  * </p>
  *
- * @author 
+ * @author
  * @since 2023-04-11
  */
 public interface ICameraTypeService extends IService<CameraType> {
 
     CameraType getByCamType(int camType);
 
+    boolean isLaser(int camType);
+
 }

+ 1 - 0
src/main/java/com/fdkankan/contro/service/ICommonService.java

@@ -1,6 +1,7 @@
 package com.fdkankan.contro.service;
 
 import com.alibaba.fastjson.JSONObject;
+import com.fdkankan.common.util.FileUtils;
 import com.fdkankan.contro.entity.*;
 import com.fdkankan.rabbitmq.bean.BuildSceneCallMessage;
 

+ 3 - 2
src/main/java/com/fdkankan/contro/service/IFdkkLaserService.java

@@ -7,8 +7,6 @@ import com.fdkankan.contro.entity.ScenePlus;
 import com.fdkankan.contro.entity.ScenePlusExt;
 import com.fdkankan.contro.entity.ScenePro;
 
-import java.util.Date;
-
 /**
  * <p>
  * TODO
@@ -33,4 +31,7 @@ public interface IFdkkLaserService {
     void sendE57ToLaser(ScenePlus scenePlus, ScenePlusExt scenePlusExt, String path);
 
     void sendRebuildE57ToLaser(ScenePlus scenePlus, ScenePlusExt scenePlusExt);
+
+    void updateStatus(String num, Integer status);
+
 }

+ 10 - 0
src/main/java/com/fdkankan/contro/service/IGenerateObjFileService.java

@@ -0,0 +1,10 @@
+package com.fdkankan.contro.service;
+
+
+import com.fdkankan.web.response.Result;
+
+public interface IGenerateObjFileService {
+
+    Result generateObjFile(String num);
+
+}

+ 9 - 0
src/main/java/com/fdkankan/contro/service/IInnerService.java

@@ -1,7 +1,16 @@
 package com.fdkankan.contro.service;
 
+import com.fdkankan.contro.entity.ScenePlus;
+
+import java.util.List;
+
 public interface IInnerService {
 
     void uploadArtificialResult(String num) throws Exception;
 
+    void updateSceneFail(String num);
+
+    List<ScenePlus> listNewCameraScene(String title, String type);
+
+    void submit(String sxNum, String qjkkNum);
 }

+ 21 - 0
src/main/java/com/fdkankan/contro/service/IRelocationBatchDetailService.java

@@ -0,0 +1,21 @@
+package com.fdkankan.contro.service;
+
+import com.fdkankan.contro.entity.RelocationBatchDetail;
+import com.baomidou.mybatisplus.extension.service.IService;
+
+import java.util.List;
+
+/**
+ * <p>
+ *  服务类
+ * </p>
+ *
+ * @author 
+ * @since 2025-09-09
+ */
+public interface IRelocationBatchDetailService extends IService<RelocationBatchDetail> {
+
+    List<RelocationBatchDetail> listByBatchId(Long batchId);
+
+
+}

+ 19 - 0
src/main/java/com/fdkankan/contro/service/IRelocationBatchService.java

@@ -0,0 +1,19 @@
+package com.fdkankan.contro.service;
+
+import com.fdkankan.contro.entity.RelocationBatch;
+import com.baomidou.mybatisplus.extension.service.IService;
+
+/**
+ * <p>
+ * 重定位批次表 服务类
+ * </p>
+ *
+ * @author 
+ * @since 2025-09-09
+ */
+public interface IRelocationBatchService extends IService<RelocationBatch> {
+
+    void relocationControl();
+
+    void relocationControlHandler(RelocationBatch relocationBatch);
+}

+ 19 - 0
src/main/java/com/fdkankan/contro/service/IRelocationInitService.java

@@ -0,0 +1,19 @@
+package com.fdkankan.contro.service;
+
+import com.fdkankan.contro.entity.RelocationInit;
+import com.baomidou.mybatisplus.extension.service.IService;
+
+/**
+ * <p>
+ *  服务类
+ * </p>
+ *
+ * @author 
+ * @since 2025-09-09
+ */
+public interface IRelocationInitService extends IService<RelocationInit> {
+
+    void pushInit(RelocationInit relocationInit);
+
+    void relocationInit();
+}

+ 114 - 0
src/main/java/com/fdkankan/contro/service/impl/BuildServiceImpl.java

@@ -0,0 +1,114 @@
+package com.fdkankan.contro.service.impl;
+
+import cn.hutool.core.collection.CollUtil;
+import cn.hutool.core.util.StrUtil;
+import com.alibaba.fastjson.JSONObject;
+import com.fdkankan.contro.service.IBuildService;
+import com.fdkankan.model.enums.ModelTypeEnums;
+import com.fdkankan.model.utils.ComputerUtil;
+import com.fdkankan.rabbitmq.bean.BuildSceneCallMessage;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.lang3.ObjectUtils;
+import org.springframework.stereotype.Service;
+
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Objects;
+
+@Slf4j
+@Service
+public class BuildServiceImpl implements IBuildService {
+
+    @Override
+    public Map<String, String> getTypeString(String cameraType, String algorithm, String resolution, JSONObject fdageData){
+        Map<String, String> map = new HashMap<>();
+        String splitType = "";
+        String skyboxType = "";
+        if(Integer.parseInt(cameraType) >= 4){
+            if("0".equals(resolution)){
+                skyboxType = "SKYBOX_V7";    //high,low,2k
+            }else {
+                skyboxType = "SKYBOX_V1";
+            }
+            splitType = "SPLIT_V1";
+
+            if(Integer.parseInt(cameraType) == 5){
+                //新双目相机
+                splitType = "SPLIT_V9";
+                skyboxType = "SKYBOX_V1";
+            }
+            if(Integer.parseInt(cameraType) == 6){
+                //小红屋新双目相机
+//                    skyboxType = "SKYBOX_V9";
+                splitType = "SPLIT_V3";
+                skyboxType = "SKYBOX_V7";
+            }
+
+            if(Integer.parseInt(cameraType) == 13){
+                //转台相机
+                skyboxType = "SKYBOX_V6";
+                splitType = "SPLIT_V12";
+                Integer location = fdageData.getInteger("location");//全景看看
+                if(Objects.nonNull(location) && location == 7){
+                    splitType = "SPLIT_V26";
+                }
+            }
+
+            if(Integer.parseInt(cameraType) == 14){
+                Integer location = fdageData.getInteger("location");
+                //转台相机
+                log.info("激光转台相机调用算法");
+                skyboxType = "SKYBOX_V11";
+                splitType = "SPLIT_V14";
+                if(location == 6){//slam
+                    splitType = "SPLIT_V25";
+                }
+                if(location == 8){//四维深巡
+                    splitType = "SPLIT_V16";
+                }
+                if (!ObjectUtils.isEmpty(fdageData)) {
+                    if ((fdageData.containsKey("exportMeshObj") && fdageData.getIntValue("exportMeshObj") == 1)) {
+                        splitType = "SPLIT_V22";
+                    }
+                    if(fdageData.containsKey("OnlyExportMeshObj")){
+                        splitType = "SPLIT_V20";
+                    }
+                }
+            }
+        }else {
+            if("sfm".equals(algorithm)){
+                splitType = "SPLIT_V2";
+                skyboxType = "SKYBOX_V1";
+            }else {
+                splitType = "SPLIT_V3";
+                skyboxType = "SKYBOX_V1";
+            }
+        }
+        if (!ObjectUtils.isEmpty(fdageData) && !ObjectUtils.isEmpty(fdageData.getString("modelType"))) {
+            switch (fdageData.getString("modelType")){
+                case ModelTypeEnums.TILE_CODE:
+                    if(skyboxType.equals("SKYBOX_V6")){
+                        skyboxType = "SKYBOX_V14";
+                    }else if(skyboxType.equals("SKYBOX_V11")){
+                        skyboxType = "SKYBOX_V15";
+                    } else{
+                        skyboxType = "SKYBOX_V13";
+                    }
+            }
+        }
+        if(StrUtil.isNotEmpty(resolution) && "6k".equals(resolution)){
+            skyboxType = "SKYBOX_V16";
+        }
+        map.put("splitType", splitType);
+        map.put("skyboxType", skyboxType);
+        return map;
+    }
+
+    @Override
+    public void writeDataJson(BuildSceneCallMessage message, JSONObject dataFdage, Map<String, String> dataMap, Map<String, Object> dataExtras) {
+        if(CollUtil.isEmpty(dataMap)){
+            dataMap = this.getTypeString(message.getCameraType(), message.getAlgorithm(), message.getResolution(), dataFdage);
+        }
+        ComputerUtil.createProjectAndDataFile(message.getPath(), message.getSceneNum(), dataMap.get("splitType"), dataMap.get("skyboxType"),null, dataExtras);
+    }
+}

+ 14 - 1
src/main/java/com/fdkankan/contro/service/impl/CameraTypeServiceImpl.java

@@ -1,18 +1,21 @@
 package com.fdkankan.contro.service.impl;
 
 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.fdkankan.common.constant.CommonStatus;
 import com.fdkankan.contro.entity.CameraType;
 import com.fdkankan.contro.mapper.ICameraTypeMapper;
 import com.fdkankan.contro.service.ICameraTypeService;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
 import org.springframework.stereotype.Service;
 
+import java.util.Objects;
+
 /**
  * <p>
  *  服务实现类
  * </p>
  *
- * @author 
+ * @author
  * @since 2023-04-11
  */
 @Service
@@ -21,4 +24,14 @@ public class CameraTypeServiceImpl extends ServiceImpl<ICameraTypeMapper, Camera
     public CameraType getByCamType(int camType) {
         return this.getOne(new LambdaQueryWrapper<CameraType>().eq(CameraType::getCameraType, camType));
     }
+
+    @Override
+    public boolean isLaser(int camType) {
+        CameraType cameraType = this.getOne(new LambdaQueryWrapper<CameraType>().eq(CameraType::getCameraType, camType));
+        if(Objects.nonNull(cameraType) && cameraType.getIsLaser() == CommonStatus.YES.code().intValue()){
+            return true;
+        }else{
+            return false;
+        }
+    }
 }

+ 19 - 3
src/main/java/com/fdkankan/contro/service/impl/CommonServiceImpl.java

@@ -6,6 +6,7 @@ import cn.hutool.core.io.FileUtil;
 import cn.hutool.core.util.ObjUtil;
 import cn.hutool.core.util.ObjectUtil;
 import cn.hutool.core.util.StrUtil;
+import cn.hutool.core.util.StrUtil;
 import cn.hutool.core.util.ZipUtil;
 import cn.hutool.http.HttpUtil;
 import com.alibaba.fastjson.JSON;
@@ -219,6 +220,13 @@ public class CommonServiceImpl implements ICommonService {
             fYunFileServiceInterface.uploadFileByCommand(localExtras, ossExtras);
         }
 
+        //上传post文件,用于深巡全景图重定位计算
+        String localPose = dataSource + "/results/pose";
+        String ossPose = ossResultPath + "pose";
+        if(FileUtil.exist(localPose)){
+            fYunFileServiceInterface.uploadFileByCommand(localPose, ossPose);
+        }
+
         //开始上传
         fYunFileServiceInterface.uploadMulFiles(uploadMap);
     }
@@ -422,7 +430,11 @@ public class CommonServiceImpl implements ICommonService {
             int imgVersion = 0;
             int linkVersion = 0;
             //获取展示页的版本号
-            String sceneJsonStr = fYunFileServiceInterface.getFileContent(String.format(UploadFilePath.DATA_VIEW_PATH, scenePlus.getNum()) + "scene.json");
+            String sceneJsonStr = null;
+            String sceneJsonKey = String.format(UploadFilePath.DATA_VIEW_PATH, scenePlus.getNum()) + "scene.json";
+            if(fYunFileService.fileExist(sceneJsonKey)){
+                sceneJsonStr = fYunFileServiceInterface.getFileContent(sceneJsonKey);
+            }
             if(StrUtil.isNotEmpty(sceneJsonStr)){
                 JSONObject sceneJson = JSON.parseObject(sceneJsonStr);
                 version = sceneJson.getIntValue("version");
@@ -466,7 +478,11 @@ public class CommonServiceImpl implements ICommonService {
                                 SceneEditControls sceneEditControls, ScenePlus scenePlus, ScenePlusExt scenePlusExt,Company company){
         String dataViewPath = String.format(UploadFilePath.DATA_VIEW_PATH, num);
 
-        String oldSceneJson = fYunFileServiceInterface.getFileContent(dataViewPath + "scene.json");
+        String sceneJsonKey = dataViewPath + "scene.json";
+        String oldSceneJson = null;
+        if(fYunFileService.fileExist(sceneJsonKey)){
+            oldSceneJson = fYunFileServiceInterface.getFileContent(sceneJsonKey);
+        }
 
         SceneJsonBean sceneJson = new SceneJsonBean();
         BeanUtil.copyProperties(sceneEditInfoExt, sceneJson, "started");
@@ -842,7 +858,7 @@ public class CommonServiceImpl implements ICommonService {
 
         Integer slamCount = null;
         String homePath = SceneUtil.getHomePath(scenePlusExt.getDataSource());
-        if(Objects.nonNull(scenePlusExt.getLocation()) && scenePlusExt.getLocation() == 6){
+        if(Objects.nonNull(scenePlusExt.getLocation()) && (scenePlusExt.getLocation() == 6 || scenePlusExt.getLocation() == 8)){
             String slamDataStr = fYunFileService.getFileContent(homePath.concat("slam_data.json"));
             JSONObject slamDataObj = JSON.parseObject(slamDataStr);
             if(Objects.nonNull(slamDataObj)){

+ 149 - 0
src/main/java/com/fdkankan/contro/service/impl/GenerateObjFileServiceImpl.java

@@ -0,0 +1,149 @@
+package com.fdkankan.contro.service.impl;
+
+import com.alibaba.fastjson.JSONObject;
+import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
+import com.fdkankan.common.constant.CommonStatus;
+import com.fdkankan.common.constant.ErrorCode;
+import com.fdkankan.common.constant.SceneConstant;
+import com.fdkankan.common.constant.SceneKind;
+import com.fdkankan.common.exception.BusinessException;
+import com.fdkankan.web.response.Result;
+import com.fdkankan.contro.entity.ScenePlus;
+import com.fdkankan.contro.entity.ScenePlusExt;
+import com.fdkankan.contro.entity.ScenePro;
+import com.fdkankan.contro.mapper.ISceneUpgradeMapper;
+import com.fdkankan.contro.service.*;
+import com.fdkankan.fyun.face.FYunFileServiceInterface;
+import com.fdkankan.rabbitmq.bean.BuildSceneCallMessage;
+import com.fdkankan.rabbitmq.util.RabbitMqProducer;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.stereotype.Service;
+import org.springframework.util.ObjectUtils;
+
+import javax.annotation.Resource;
+import java.util.Objects;
+
+@Service
+public class GenerateObjFileServiceImpl implements IGenerateObjFileService {
+
+    @Value("${queue.modeling.obj.modeling-pre}")
+    private String queueObjModelingPre;
+
+    @Autowired
+    private ISceneProService sceneProService;
+    @Autowired
+    private IScenePlusService scenePlusService;
+    @Autowired
+    private IScenePlusExtService scenePlusExtService;
+    @Resource
+    private FYunFileServiceInterface fYunFileService;
+    @Resource
+    private RabbitMqProducer mqProducer;
+    @Autowired
+    private ISceneUpgradeMapper sceneUpgradeMapper;
+
+    @Override
+    public Result generateObjFile(String num) {
+        ScenePro sceneProEntity = sceneProService.getByNum(num);
+
+        //v4版本生成obj
+        if(ObjectUtils.isEmpty(sceneProEntity) || sceneProEntity.getIsUpgrade() == CommonStatus.YES.code().intValue()){
+            return generatePlusObjFile(num);
+        }
+        //v3版本生成obj
+        return generateProObjFile(num);
+    }
+
+    public Result generateProObjFile(String num) {
+        ScenePro sceneProEntity = sceneProService.getByNum(num);
+        if(sceneProEntity.getSceneSource() != 4 && sceneProEntity.getSceneSource() != 5){
+            return Result.failure(ErrorCode.FAILURE_CODE_3003.code(), "只能操作激光场景");
+        }
+
+        // 拷贝文件
+        String path = sceneProEntity.getDataSource();
+        String ossPath = path.replace("/mnt/data","home")+"/data.fdage";
+        if(!fYunFileService.fileExist(ossPath)){
+            return Result.failure(ErrorCode.FAILURE_CODE_3037.code(), "场景原始数据已过期,无法使用该功能!");
+        }
+
+        LambdaUpdateWrapper<ScenePro> updateWrapper = new LambdaUpdateWrapper<>();
+        updateWrapper
+                .set(ScenePro::getStatus, 0)
+                .set(ScenePro::getIsObj, 1)
+                .set(ScenePro::getIsUpgrade, 2)   //   升级中
+                .eq(ScenePro::getNum, sceneProEntity.getNum());
+        if(Objects.nonNull(sceneProEntity.getLaserTitle())){
+            updateWrapper.set(ScenePro::getSceneName, sceneProEntity.getLaserTitle());
+        }
+        sceneProService.update(updateWrapper);
+
+        // 获取最新的场景名称
+        //同步到scenePlus、scenePlus
+        ScenePlus scenePlus = scenePlusService.getScenePlusByNum(num);
+        if(Objects.nonNull(scenePlus)){
+            sceneUpgradeMapper.deleteScenePlus(num);
+            sceneUpgradeMapper.deleteScenePlusExt(scenePlus.getId());
+        }
+        sceneUpgradeMapper.transferScenePlus(num);
+        scenePlus = scenePlusService.getScenePlusByNum(num);
+        String sceneKind = sceneProEntity.getSceneScheme() == 3 ? SceneKind.FACE.code():SceneKind.TILES.code();
+        sceneUpgradeMapper.transferScenePlusExt(num, scenePlus.getId(), sceneKind);
+
+
+        // 发送MQ
+        BuildSceneCallMessage mqMsg = new BuildSceneCallMessage();
+        mqMsg.setSceneNum(sceneProEntity.getNum());
+        mqMsg.setAlgorithm(sceneProEntity.getAlgorithm());
+        mqMsg.setBuildType(sceneProEntity.getBuildType());
+        mqMsg.setPath(sceneProEntity.getDataSource());
+        mqProducer.sendByWorkQueue(queueObjModelingPre,mqMsg);
+
+        return Result.success();
+    }
+
+    public Result generatePlusObjFile(String num) {
+        ScenePlus scenePlus = scenePlusService.getScenePlusByNum(num);
+
+        if(ObjectUtils.isEmpty(scenePlus)){
+            return Result.failure(SceneConstant.FAILURE_CODE_5005, SceneConstant.FAILURE_MSG_5005);
+        }
+
+        if(scenePlus.getSceneSource() != 4 && scenePlus.getSceneSource() !=5){
+            return Result.failure(ErrorCode.FAILURE_CODE_3003.code(), "只能操作激光场景");
+        }
+
+        ScenePlusExt scenePlusExt = scenePlusExtService.getScenePlusExtByPlusId(scenePlus.getId());
+
+        String ossPath = scenePlusExt.getDataSource().replace("/mnt/data","home")+"/data.fdage";
+        if(!fYunFileService.fileExist(ossPath)){
+            return Result.failure(ErrorCode.FAILURE_CODE_3037.code(), "场景原始数据已过期,无法使用该功能!");
+        }
+
+        LambdaUpdateWrapper<ScenePlus> updateWrapper = new LambdaUpdateWrapper<>();
+        updateWrapper
+                .set(ScenePlus::getSceneStatus, 0)
+                .eq(ScenePlus::getNum, num);
+        if(Objects.nonNull(scenePlus.getLaserTitle())){
+            updateWrapper.set(ScenePlus::getTitle, scenePlus.getLaserTitle());
+        }
+        scenePlusService.update(updateWrapper);
+
+        LambdaUpdateWrapper<ScenePlusExt> plusExtUpdateWrapper = new LambdaUpdateWrapper<>();
+        plusExtUpdateWrapper
+                .set(ScenePlusExt::getIsObj, 1)
+                .eq(ScenePlusExt::getPlusId, scenePlus.getId());
+        scenePlusExtService.update(plusExtUpdateWrapper);
+
+        // 发送MQ
+        BuildSceneCallMessage mqMsg = new BuildSceneCallMessage();
+        mqMsg.setSceneNum(num);
+        mqMsg.setAlgorithm(scenePlusExt.getAlgorithm());
+        mqMsg.setBuildType(scenePlusExt.getBuildType());
+        mqMsg.setPath(scenePlusExt.getDataSource());
+        mqProducer.sendByWorkQueue(queueObjModelingPre,mqMsg);
+
+        return Result.success();
+    }
+}

+ 21 - 1
src/main/java/com/fdkankan/contro/service/impl/IFdkkLaserServiceImpl.java

@@ -57,12 +57,17 @@ public class IFdkkLaserServiceImpl implements IFdkkLaserService {
 
     @Value("${4dkk.laserService.cloud-point-fyun-path}")
     private String cloudPointFyunPath;
+    @Value("${queue.application.laser.update-laser-scene-status:update-laser-scene-status}")
+    private String updateLaserSceneStatus;
     @Autowired
     private IUserService userService;
 
     @Resource
     private FYunFileServiceInterface fYunFileService;
-
+    @Autowired
+    private ICameraTypeService cameraTypeService;
+    @Autowired
+    private ICameraDetailService cameraDetailService;
 
     public void syncBuildResult(SyncLaserResultBean laserResultBean) {
         log.info("激光转台相机构建结果 同步 请求 ");
@@ -249,6 +254,20 @@ public class IFdkkLaserServiceImpl implements IFdkkLaserService {
         }
     }
 
+    @Override
+    public void updateStatus(String num, Integer status) {
+        ScenePlus scenePlus = scenePlusService.getScenePlusByNum(num);
+        CameraDetail cameraDetail = cameraDetailService.getByCameraId(scenePlus.getCameraId());
+        boolean laser = cameraTypeService.isLaser(cameraDetail.getType());
+        if(!laser){
+            return;
+        }
+        JSONObject jsonObject = new JSONObject();
+        jsonObject.put("sceneCodes", Arrays.asList(num));
+        jsonObject.put("status", status);
+        rabbitMqProducer.sendByWorkQueue(updateLaserSceneStatus, jsonObject);
+    }
+
     public void sendRebuildE57ToLaser(ScenePlus scenePlus, ScenePlusExt scenePlusExt) {
         User user = userService.getById(scenePlus.getUserId());
         Map<String, Object> params = new HashMap<>();
@@ -299,4 +318,5 @@ public class IFdkkLaserServiceImpl implements IFdkkLaserService {
 
         return null;
     }
+
 }

+ 70 - 0
src/main/java/com/fdkankan/contro/service/impl/InnerServiceImpl.java

@@ -6,12 +6,14 @@ import cn.hutool.http.ContentType;
 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.fdkankan.common.constant.*;
 import com.fdkankan.common.exception.BusinessException;
 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.enums.CameraTypeEnum;
 import com.fdkankan.contro.service.*;
 import com.fdkankan.fyun.config.FYunFileConfig;
 import com.fdkankan.fyun.face.FYunFileServiceInterface;
@@ -21,6 +23,8 @@ import com.fdkankan.model.constants.UploadFilePath;
 import com.fdkankan.model.enums.ModelTypeEnums;
 import com.fdkankan.model.utils.CreateHouseJsonUtil;
 import com.fdkankan.model.utils.SceneUtil;
+import com.fdkankan.rabbitmq.bean.BuildSceneCallMessage;
+import com.fdkankan.rabbitmq.util.RabbitMqProducer;
 import org.apache.commons.lang3.ObjectUtils;
 import org.apache.http.HttpHeaders;
 import org.springframework.beans.factory.annotation.Autowired;
@@ -30,7 +34,9 @@ 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.*;
+import java.util.stream.Collectors;
 
 @Service
 public class InnerServiceImpl implements IInnerService {
@@ -54,6 +60,8 @@ public class InnerServiceImpl implements IInnerService {
     private ICompanyService companyService;
     @Resource
     private FYunFileConfig fYunFileConfig;
+    @Autowired
+    private RabbitMqProducer mqProducer;
 
     @Override
     public void uploadArtificialResult(String num) throws Exception {
@@ -173,6 +181,19 @@ public class InnerServiceImpl implements IInnerService {
         scenePlusExtService.updateById(scenePlusExt);
     }
 
+    @Override
+    public void updateSceneFail(String num) {
+        ScenePlus scenePlus = scenePlusService.getScenePlusByNum(num);
+        scenePlus.setSceneStatus(500);
+        scenePlusService.updateById(scenePlus);
+
+        String statusJsonKey = String.format(UploadFilePath.DATA_VIEW_PATH, num) + "status.json";
+        String fileContent = fYunFileService.getFileContent(statusJsonKey);
+        JSONObject jsonObject = JSON.parseObject(fileContent);
+        jsonObject.put("status", -1);
+        fYunFileService.uploadFile(jsonObject.toJSONString().getBytes(StandardCharsets.UTF_8), statusJsonKey);
+    }
+
     private void uploadStatusJson(ScenePlus scenePlus, ScenePlusExt scenePlusExt){
         String num = scenePlus.getNum();
         String dataViewPath = String.format(UploadFilePath.DATA_VIEW_PATH, num);
@@ -336,4 +357,53 @@ public class InnerServiceImpl implements IInnerService {
 
         return result;
     }
+
+    @Override
+    public List<ScenePlus> listNewCameraScene(String title, String type) {
+        LambdaQueryWrapper<ScenePlus> queryWrapper = new LambdaQueryWrapper<ScenePlus>()
+                .like(ScenePlus::getTitle, title)
+                .ne(ScenePlus::getSceneStatus, SceneStatus.wait.code())
+                .orderByDesc(ScenePlus::getId).last("limit 5");
+        if("SX".equalsIgnoreCase(type)){
+            List<CameraDetail> list = cameraDetailService.list(new LambdaQueryWrapper<CameraDetail>().eq(CameraDetail::getType, CameraTypeEnum.LASER_SX.getType()));
+            Set<Long> cameraIds = list.stream().map(v -> v.getCameraId()).collect(Collectors.toSet());
+            queryWrapper.in(ScenePlus::getCameraId, cameraIds);
+        }else{
+            queryWrapper.eq(ScenePlus::getSceneSource, SceneSource.QJKK.code());
+        }
+        return scenePlusService.list(queryWrapper);
+    }
+
+    @Override
+    public void submit(String sxNum, String qjkkNum) {
+        ScenePlus sxScene = scenePlusService.getScenePlusByNum(sxNum);
+        if(sxScene == null){
+            throw new BusinessException(ErrorCode.FAILURE_CODE_5005);
+        }
+        if(sxScene.getSceneStatus().equals(SceneStatus.wait.code())){
+            throw new BusinessException(ErrorCode.FAILURE_CODE_5033);
+        }
+        ScenePlus qjkkScene = scenePlusService.getScenePlusByNum(qjkkNum);
+        if(qjkkScene == null){
+            throw new BusinessException(ErrorCode.FAILURE_CODE_5005);
+        }
+        if(qjkkScene.getSceneStatus().equals(SceneStatus.wait.code())){
+            throw new BusinessException(ErrorCode.FAILURE_CODE_5033);
+        }
+        Map<String, Object> params = new HashMap<>();
+        params.put("sxNum", sxNum);
+        params.put("qjkkNum", qjkkNum);
+
+        ScenePlusExt scenePlusExtByPlusId = scenePlusExtService.getScenePlusExtByPlusId(sxScene.getId());
+        BuildSceneCallMessage buildSceneCallMessage = new BuildSceneCallMessage();
+        buildSceneCallMessage.setSceneNum(sxNum);
+        buildSceneCallMessage.setBizType("relocation");
+        buildSceneCallMessage.setExt(params);
+        buildSceneCallMessage.setPath(scenePlusExtByPlusId.getDataSource() + "_relocation");
+        buildSceneCallMessage.setCameraType("14");
+        mqProducer.sendByWorkQueue("modeling-sx-pre", buildSceneCallMessage);
+
+        sxScene.setSceneStatus(SceneStatus.wait.code());
+        scenePlusService.updateById(sxScene);
+    }
 }

+ 27 - 0
src/main/java/com/fdkankan/contro/service/impl/RelocationBatchDetailServiceImpl.java

@@ -0,0 +1,27 @@
+package com.fdkankan.contro.service.impl;
+
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.fdkankan.contro.entity.RelocationBatchDetail;
+import com.fdkankan.contro.mapper.IRelocationBatchDetailMapper;
+import com.fdkankan.contro.service.IRelocationBatchDetailService;
+import org.springframework.stereotype.Service;
+
+import java.util.List;
+
+/**
+ * <p>
+ *  服务实现类
+ * </p>
+ *
+ * @author 
+ * @since 2025-09-09
+ */
+@Service
+public class RelocationBatchDetailServiceImpl extends ServiceImpl<IRelocationBatchDetailMapper, RelocationBatchDetail> implements IRelocationBatchDetailService {
+
+    @Override
+    public List<RelocationBatchDetail> listByBatchId(Long batchId) {
+        return this.list(new LambdaQueryWrapper<RelocationBatchDetail>().eq(RelocationBatchDetail::getBatchId, batchId));
+    }
+}

+ 84 - 0
src/main/java/com/fdkankan/contro/service/impl/RelocationBatchServiceImpl.java

@@ -0,0 +1,84 @@
+package com.fdkankan.contro.service.impl;
+
+import cn.hutool.core.collection.CollUtil;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.fdkankan.contro.entity.RelocationBatch;
+import com.fdkankan.contro.entity.ScenePlus;
+import com.fdkankan.contro.entity.ScenePlusExt;
+import com.fdkankan.contro.mapper.IRelocationBatchMapper;
+import com.fdkankan.contro.service.IRelocationBatchService;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.fdkankan.contro.service.IScenePlusExtService;
+import com.fdkankan.contro.service.IScenePlusService;
+import com.fdkankan.rabbitmq.bean.BuildSceneCallMessage;
+import com.fdkankan.rabbitmq.util.RabbitMqProducer;
+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 javax.annotation.Resource;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * <p>
+ * 重定位批次表 服务实现类
+ * </p>
+ *
+ * @author 
+ * @since 2025-09-09
+ */
+@Slf4j
+@Service
+public class RelocationBatchServiceImpl extends ServiceImpl<IRelocationBatchMapper, RelocationBatch> implements IRelocationBatchService {
+
+    @Value("${queue.modeling.relocation.relocation-pre:sx-relocation-pre}")
+    private String queueModelingPre;
+    @Autowired
+    private IScenePlusService scenePlusService;
+    @Autowired
+    private IScenePlusExtService scenePlusExtService;
+    @Resource
+    private RabbitMqProducer mqProducer;
+
+    @Override
+    public void relocationControl() {
+        List<RelocationBatch> list = this.list(new LambdaQueryWrapper<RelocationBatch>().eq(RelocationBatch::getStatus, 0));
+        if(CollUtil.isEmpty(list)){
+            return;
+        }
+        for (RelocationBatch relocationBatch : list) {
+            try {
+                List<RelocationBatch> buildingList= this.list(new LambdaQueryWrapper<RelocationBatch>().eq(RelocationBatch::getNum, relocationBatch.getNum()).eq(RelocationBatch::getStatus, 1));
+                if(CollUtil.isNotEmpty(buildingList)){
+                    continue;
+                }
+                this.relocationControlHandler(relocationBatch);
+            }catch (Exception e){
+                log.error("重定位调度失败,num:{}, batchId:{}", relocationBatch.getNum(), relocationBatch.getId(), e);
+            }
+        }
+
+    }
+
+    @Override
+    public void relocationControlHandler(RelocationBatch relocationBatch) {
+        ScenePlus scenePlus = scenePlusService.getScenePlusByNum(relocationBatch.getNum());
+        ScenePlusExt scenePlusExt = scenePlusExtService.getScenePlusExtByPlusId(scenePlus.getId());
+        String path = scenePlusExt.getDataSource() + "_relocation";
+        BuildSceneCallMessage buildSceneMessage = new BuildSceneCallMessage();
+        buildSceneMessage.setSceneNum(relocationBatch.getNum());
+        buildSceneMessage.setBizType("relocation");
+        buildSceneMessage.setPath(path);
+        buildSceneMessage.setCameraType("14");
+        Map<String, Object> ext = new HashMap<>();
+        ext.put("batchId", relocationBatch.getId());
+        buildSceneMessage.setExt(ext);
+        mqProducer.sendByWorkQueue(queueModelingPre, buildSceneMessage);
+        relocationBatch.setStatus(1);
+        relocationBatch.setUpdateTime(null);
+        this.updateById(relocationBatch);
+    }
+}

+ 100 - 0
src/main/java/com/fdkankan/contro/service/impl/RelocationInitServiceImpl.java

@@ -0,0 +1,100 @@
+package com.fdkankan.contro.service.impl;
+
+import cn.hutool.core.collection.CollUtil;
+import cn.hutool.core.date.DateUtil;
+import cn.hutool.core.util.StrUtil;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.fdkankan.common.constant.CommonSuccessStatus;
+import com.fdkankan.common.constant.SceneStatus;
+import com.fdkankan.contro.entity.RelocationInit;
+import com.fdkankan.contro.entity.ScenePlus;
+import com.fdkankan.contro.mapper.IRelocationInitMapper;
+import com.fdkankan.contro.service.IRelocationInitService;
+import com.fdkankan.contro.service.IScenePlusService;
+import com.fdkankan.rabbitmq.util.RabbitMqProducer;
+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 javax.annotation.Resource;
+import java.util.*;
+
+/**
+ * <p>
+ *  服务实现类
+ * </p>
+ *
+ * @author 
+ * @since 2025-09-09
+ */
+@Slf4j
+@Service
+public class RelocationInitServiceImpl extends ServiceImpl<IRelocationInitMapper, RelocationInit> implements IRelocationInitService {
+
+    @Value("${queue.modeling.relocation.relocation-scene-init:relocation-scene-init}")
+    private String queueRelocationSceneInit;
+    @Resource
+    private RabbitMqProducer mqProducer;
+    @Autowired
+    private IScenePlusService scenePlusService;
+
+    @Override
+    public void pushInit(RelocationInit relocationInit) {
+        try {
+            ScenePlus qjkk = scenePlusService.getScenePlusByNum(relocationInit.getPanNum());
+            if(qjkk.getSceneStatus() != SceneStatus.NO_DISPLAY.code() && qjkk.getSceneStatus() != SceneStatus.SUCCESS.code()){
+                return;
+            }
+            ScenePlus sx = null;
+            if(StrUtil.isNotEmpty(relocationInit.getNum())){
+                sx = scenePlusService.getScenePlusByNum(relocationInit.getNum());
+            }else{
+                sx = scenePlusService.getByFileId(relocationInit.getUnicode());
+            }
+            if(Objects.isNull(sx) || (sx.getSceneStatus() != SceneStatus.NO_DISPLAY.code() && sx.getSceneStatus() != SceneStatus.SUCCESS.code())){
+                if(Objects.nonNull(sx)){
+                    relocationInit.setNum(sx.getNum());
+                    relocationInit.setUpdateTime(null);
+                    this.updateById(relocationInit);
+                }
+                return;
+            }
+            ScenePlus panNum = scenePlusService.getScenePlusByNum(relocationInit.getPanNum());
+            if(panNum.getSceneStatus() != SceneStatus.NO_DISPLAY.code() && panNum.getSceneStatus() != SceneStatus.SUCCESS.code()){
+                return;
+            }
+            Map<String, String> map = new HashMap<>();
+            map.put("sxNum", relocationInit.getNum());
+            map.put("qjkkNum",relocationInit.getPanNum());
+            mqProducer.sendByWorkQueue(queueRelocationSceneInit, map);
+
+            relocationInit.setNum(sx.getNum());
+            relocationInit.setStatus(CommonSuccessStatus.SUCCESS.code());
+            relocationInit.setUpdateTime(null);
+            this.updateById(relocationInit);
+        }catch (Exception e){
+            log.error("重定位初始化推送报错, relocationInit-id:{}", relocationInit.getId(), e);
+        }finally {
+            //如果等待状态持续一个星期,可以认为这个记录由于各种未知情况,推送不出去,置为失败
+            if(relocationInit.getStatus() == CommonSuccessStatus.WAITING.code() && relocationInit.getCreateTime().before(DateUtil.offsetDay(new Date(), -7))){
+                relocationInit.setStatus(CommonSuccessStatus.FAIL.code());
+                relocationInit.setUpdateTime(null);
+                this.updateById(relocationInit);
+            }
+        }
+
+    }
+
+    @Override
+    public void relocationInit() {
+        List<RelocationInit> list = this.list(new LambdaQueryWrapper<RelocationInit>().eq(RelocationInit::getStatus, 0));
+        if(CollUtil.isEmpty(list)){
+            return;
+        }
+        for (RelocationInit relocationInit : list) {
+            this.pushInit(relocationInit);
+        }
+    }
+}

文件差異過大導致無法顯示
+ 272 - 249
src/main/java/com/fdkankan/contro/service/impl/SceneFileBuildServiceImpl.java


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

@@ -2,4 +2,8 @@ spring:
   profiles:
     active: test
   application:
-    name: model-control
+    name: model-control
+
+# 不配默认为false
+tlog:
+  enable-invoke-time-print: true

+ 172 - 196
src/main/resources/logback-nacos.xml

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

+ 5 - 0
src/main/resources/mapper/contro/RelocationBatchDetailMapper.xml

@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="com.fdkankan.contro.mapper.IRelocationBatchDetailMapper">
+
+</mapper>

+ 5 - 0
src/main/resources/mapper/contro/RelocationBatchMapper.xml

@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="com.fdkankan.contro.mapper.IRelocationBatchMapper">
+
+</mapper>

+ 5 - 0
src/main/resources/mapper/contro/RelocationInitMapper.xml

@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="com.fdkankan.contro.mapper.IRelocationInitMapper">
+
+</mapper>