dengsixing 3 月之前
父節點
當前提交
cecd8fee5a

+ 4 - 3
src/main/java/com/fdkankan/modeling/ModelingApplication.java

@@ -1,15 +1,15 @@
 package com.fdkankan.modeling;
 
-import com.fdkankan.modeling.config.rabbitmq.RabbitMQConstant;
+import cn.hutool.core.io.FileUtil;
 import org.mybatis.spring.annotation.MapperScan;
-import org.springframework.amqp.core.Queue;
 import org.springframework.boot.SpringApplication;
 import org.springframework.boot.autoconfigure.SpringBootApplication;
 import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
-import org.springframework.context.annotation.Bean;
 import org.springframework.context.annotation.ComponentScan;
 import org.springframework.scheduling.annotation.EnableScheduling;
 
+import java.util.UUID;
+
 @SpringBootApplication
 @EnableScheduling
 @ComponentScan(basePackages = {"com.fdkankan.*"})
@@ -18,6 +18,7 @@ import org.springframework.scheduling.annotation.EnableScheduling;
 public class ModelingApplication {
 
 	public static void main(String[] args) {
+		FileUtil.writeUtf8String("interrupt-calling-" + UUID.randomUUID().toString().replace("-",""), "/opt/queue-name-interrupt-calling.txt");
 		SpringApplication.run(ModelingApplication.class, args);
 	}
 

+ 0 - 33
src/main/java/com/fdkankan/modeling/config/rabbitmq/BindingConfig.java

@@ -1,33 +0,0 @@
-package com.fdkankan.modeling.config.rabbitmq;
-
-import com.rabbitmq.client.ConnectionFactory;
-import lombok.extern.slf4j.Slf4j;
-import org.springframework.amqp.core.Binding;
-import org.springframework.amqp.core.BindingBuilder;
-import org.springframework.amqp.rabbit.connection.CachingConnectionFactory;
-import org.springframework.context.annotation.Bean;
-import org.springframework.context.annotation.Configuration;
-import org.springframework.context.annotation.Primary;
-
-import javax.annotation.Resource;
-
-@Configuration
-@Slf4j
-public class BindingConfig {
-
-    @Resource
-    private QueueConfig queueConfig;
-    @Resource
-    private ExchangeConfig exchangeConfig;
-
-
-    /**
-     * 将消息队列和交换机进行绑定,指定路由
-     */
-    @Bean
-    public Binding bindingFanout() {
-        return BindingBuilder.bind(queueConfig.fanoutQueue()).to(exchangeConfig.fanoutExchange());
-    }
-
-
-}

+ 0 - 25
src/main/java/com/fdkankan/modeling/config/rabbitmq/ExchangeConfig.java

@@ -1,25 +0,0 @@
-package com.fdkankan.modeling.config.rabbitmq;
-
-import org.springframework.amqp.core.DirectExchange;
-import org.springframework.amqp.core.FanoutExchange;
-import org.springframework.amqp.core.TopicExchange;
-import org.springframework.context.annotation.Bean;
-import org.springframework.context.annotation.Configuration;
-
-@Configuration
-public class ExchangeConfig {
-
-    /**
-     * 交换机说明:
-     * durable="true" rabbitmq重启的时候不需要创建新的交换机
-     * auto-delete 表示交换机没有在使用时将被自动删除 默认是false
-     * direct交换器相对来说比较简单,匹配规则为:如果路由键匹配,消息就被投送到相关的队列
-     * topic交换器你采用模糊匹配路由键的原则进行转发消息到队列中
-     * fanout交换器中没有路由键的概念,他会把消息发送到所有绑定在此交换器上面的队列中。
-     */
-    @Bean(name = RabbitMQConstant.EXCHANGE_FANOUT_INTERRUPT_CALLING)
-    public FanoutExchange fanoutExchange() {
-        return new FanoutExchange(RabbitMQConstant.EXCHANGE_FANOUT_INTERRUPT_CALLING, true, false);
-    }
-
-}

+ 0 - 21
src/main/java/com/fdkankan/modeling/config/rabbitmq/QueueConfig.java

@@ -1,21 +0,0 @@
-package com.fdkankan.modeling.config.rabbitmq;
-
-import org.springframework.amqp.core.Queue;
-import org.springframework.context.annotation.Bean;
-import org.springframework.context.annotation.Configuration;
-
-@Configuration
-public class QueueConfig {
-
-    /**
-     * durable="true" 持久化 rabbitmq重启的时候不需要创建新的队列
-     * exclusive 表示该消息队列是否只在当前connection生效,默认是false
-     * auto-delete 表示消息队列没有在使用时将被自动删除 默认是false
-     */
-
-    @Bean(name = RabbitMQConstant.QUEUE_FANOUT)
-    public Queue fanoutQueue() {
-        return new Queue(RabbitMQConstant.QUEUE_FANOUT, true, false, false);
-    }
-
-}

+ 2 - 2
src/main/java/com/fdkankan/modeling/config/rabbitmq/RabbitMQConstant.java

@@ -3,11 +3,11 @@
 // (powered by FernFlower decompiler)
 //
 
-package com.fdkankan.modeling.config.rabbitmq;
+package com.fdkankan.modeling.constants;
 
 public class RabbitMQConstant {
 
-    public static final String QUEUE_FANOUT = "fanout-interrupt-calling";
+    public static String QUEUE_FANOUT = "fanout-interrupt-calling";
 
     public static final String EXCHANGE_FANOUT_INTERRUPT_CALLING = "fanout-exchange-iterrupt-calling";
 }

+ 7 - 1
src/main/java/com/fdkankan/modeling/handler/LaserSceneObjGenerateHandler.java

@@ -1,8 +1,11 @@
 package com.fdkankan.modeling.handler;
 
 import com.alibaba.fastjson.JSONObject;
+import com.fdkankan.common.constant.ErrorCode;
+import com.fdkankan.common.exception.BusinessException;
 import com.fdkankan.model.utils.ComputerUtil;
 import com.fdkankan.model.utils.CreateObjUtil;
+import com.fdkankan.modeling.constants.SysConstants;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.stereotype.Component;
@@ -31,7 +34,10 @@ public class LaserSceneObjGenerateHandler implements SceneHandler {
             ComputerUtil.createProjectAndDataFile(laserObjFilePath, projectNum, dataMap.get("splitType"),
                     dataMap.get("skyboxType"), null, dataExtras);
 
-            //计算模型并返回需要上传oss的文件集合
+            //场景已删除,不启动算法进程
+            if(SysConstants.interrupCallingNums.contains(projectNum)){
+                throw new BusinessException(ErrorCode.APP_ID_ILLEGAL);
+            }
             CreateObjUtil.build3dModel(laserObjFilePath, "");
 
             log.info("OBJ文件生成完成");

+ 14 - 34
src/main/java/com/fdkankan/modeling/receiver/InterruptCallingListener.java

@@ -2,25 +2,23 @@ package com.fdkankan.modeling.receiver;
 
 import cn.hutool.core.collection.CollUtil;
 import cn.hutool.core.io.FileUtil;
+import com.alibaba.fastjson.JSON;
+import com.alibaba.fastjson.JSONObject;
 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.fdkankan.model.utils.CreateObjUtil;
-import com.fdkankan.modeling.config.rabbitmq.RabbitMQConstant;
+import com.fdkankan.modeling.constants.RabbitMQConstant;
 import com.fdkankan.modeling.constants.SysConstants;
 import com.fdkankan.modeling.entity.BuildLog;
-import com.fdkankan.modeling.handler.LaserSceneObjGenerateHandler;
 import com.fdkankan.modeling.service.IBuildLogService;
-import com.fdkankan.modeling.service.IBuildService;
-import com.fdkankan.modeling.service.ISceneBuildProcessLogService;
-import com.fdkankan.rabbitmq.util.RabbitMqProducer;
-import com.fdkankan.redis.util.RedisLockUtil;
-import com.fdkankan.redis.util.RedisUtil;
 import com.rabbitmq.client.Channel;
 import lombok.extern.slf4j.Slf4j;
+import org.springframework.amqp.core.ExchangeTypes;
 import org.springframework.amqp.core.Message;
+import org.springframework.amqp.rabbit.annotation.Exchange;
 import org.springframework.amqp.rabbit.annotation.Queue;
+import org.springframework.amqp.rabbit.annotation.QueueBinding;
 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;
@@ -38,45 +36,27 @@ import java.util.List;
 @Component
 public class InterruptCallingListener {
 
-    @Value("${queue.modeling.modeling-call}")
-    private String queueModelingCall;
-    @Value("${queue.modeling.modeling-post}")
-    private String queueModelingPost;
-    @Value("${queue.modeling.modeling-process-log}")
-    private String queueModelingProcessLog;
-
-    @Autowired
-    private RedisUtil redisUtil;
-
-    @Autowired
-    private RedisLockUtil redisLockUtil;
-
-    @Autowired
-    private RabbitMqProducer rabbitMqProducer;
-
     @Autowired
     private IBuildLogService buildLogService;
 
-    @Autowired
-    private LaserSceneObjGenerateHandler laserSceneObjGenerateHandler;
-    @Autowired
-    private ISceneBuildProcessLogService sceneBuildProcessLogService;
-
-    @Autowired
-    private IBuildService buildService;
-
     /**
      * @throws Exception
      */
     @RabbitListener(
-            queuesToDeclare = @Queue(RabbitMQConstant.QUEUE_FANOUT)
+            bindings = @QueueBinding(
+                    value = @Queue("#{queueNameService.getInterruptCallingQueueName()}"), // 匿名队列(随机生成队列名,非持久)
+                    exchange = @Exchange(name = RabbitMQConstant.EXCHANGE_FANOUT_INTERRUPT_CALLING, type = ExchangeTypes.FANOUT),
+                    key = "" // Fanout 交换机忽略路由键
+            )
     )
     public void buildSceneHandler(Channel channel, Message message) throws Exception {
         SysConstants.SYSTEM_BUILDING = true;
         long deliveryTag = message.getMessageProperties().getDeliveryTag();
 
         try {
-            String num = new String(message.getBody(), StandardCharsets.UTF_8);
+            String msg = new String(message.getBody(), StandardCharsets.UTF_8);
+            JSONObject jsonObject = JSON.parseObject(msg);
+            String num = jsonObject.getString("num");
 
             log.info("接收到请求:{}", num);
 

+ 20 - 0
src/main/java/com/fdkankan/modeling/receiver/QueueNameService.java

@@ -0,0 +1,20 @@
+package com.fdkankan.modeling.receiver;
+
+import cn.hutool.core.io.FileUtil;
+import cn.hutool.core.util.StrUtil;
+import com.fdkankan.modeling.constants.RabbitMQConstant;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.stereotype.Service;
+
+@Service
+@Slf4j
+public class QueueNameService {
+
+    public String getInterruptCallingQueueName(){
+        String queueName = FileUtil.readUtf8String("/opt/queue-name-interrupt-calling.txt");
+        if(StrUtil.isEmpty(queueName)){
+            queueName = RabbitMQConstant.QUEUE_FANOUT;
+        }
+        return queueName;
+    }
+}

+ 474 - 462
src/main/java/com/fdkankan/modeling/receiver/RabbitMqListener.java

@@ -1,462 +1,474 @@
-//package com.fdkankan.modeling.receiver;
-//
-//import cn.hutool.core.collection.CollUtil;
-//import cn.hutool.core.io.FileUtil;
-//import cn.hutool.core.io.watch.WatchMonitor;
-//import cn.hutool.core.io.watch.Watcher;
-//import cn.hutool.core.lang.Console;
-//import cn.hutool.core.util.ObjectUtil;
-//import cn.hutool.core.util.StrUtil;
-//import com.alibaba.fastjson.JSON;
-//import com.alibaba.fastjson.JSONArray;
-//import com.alibaba.fastjson.JSONObject;
-//import com.fdkankan.common.constant.CommonOperStatus;
-//import com.fdkankan.common.constant.ModelingBuildStatus;
-//import com.fdkankan.common.util.CmdUtils;
-//import com.fdkankan.common.util.FileUtils;
-//import com.fdkankan.model.constants.ConstantFilePath;
-//import com.fdkankan.model.utils.ComputerUtil;
-//import com.fdkankan.model.utils.CreateObjUtil;
-//import com.fdkankan.modeling.bean.BuildSceneResultBean;
-//import com.fdkankan.modeling.constants.CmdConstant;
-//import com.fdkankan.modeling.constants.SysConstants;
-//import com.fdkankan.modeling.entity.BuildLog;
-//import com.fdkankan.modeling.exception.BuildException;
-//import com.fdkankan.modeling.handler.LaserSceneObjGenerateHandler;
-//import com.fdkankan.modeling.service.IBuildLogService;
-//import com.fdkankan.modeling.service.IBuildService;
-//import com.fdkankan.modeling.service.ISceneBuildProcessLogService;
-//import com.fdkankan.rabbitmq.bean.BuildSceneCallMessage;
-//import com.fdkankan.rabbitmq.bean.BuildSceneProcessLogMessage;
-//import com.fdkankan.rabbitmq.bean.BuildSceneResultMqMessage;
-//import com.fdkankan.rabbitmq.util.RabbitMqProducer;
-//import com.fdkankan.redis.util.RedisLockUtil;
-//import com.fdkankan.redis.util.RedisUtil;
-//import com.rabbitmq.client.Channel;
-//import com.fdkankan.model.constants.SceneBuildProcessType;
-//import lombok.extern.slf4j.Slf4j;
-//import org.apache.commons.lang3.StringUtils;
-//import org.apache.commons.lang3.time.StopWatch;
-//import org.springframework.amqp.core.Message;
-//import org.springframework.amqp.rabbit.annotation.Queue;
-//import org.springframework.amqp.rabbit.annotation.RabbitListener;
-//import org.springframework.beans.factory.annotation.Autowired;
-//import org.springframework.beans.factory.annotation.Value;
-//import org.springframework.stereotype.Component;
-//import org.springframework.util.ObjectUtils;
-//import java.io.File;
-//import java.nio.charset.StandardCharsets;
-//import java.nio.file.Path;
-//import java.nio.file.WatchEvent;
-//import java.util.*;
-//import java.util.concurrent.Future;
-//import java.util.concurrent.TimeUnit;
-//import java.util.concurrent.TimeoutException;
-//
-///**
-// * <p>
-// * TODO
-// * </p>
-// *
-// * @author dengsixing
-// * @since 2022/4/20
-// **/
-//@Slf4j
-//@Component
-//public class RabbitMqListener {
-//
-//    @Value("${queue.modeling.modeling-call}")
-//    private String queueModelingCall;
-//    @Value("${queue.modeling.modeling-post}")
-//    private String queueModelingPost;
-//    @Value("${queue.modeling.modeling-process-log}")
-//    private String queueModelingProcessLog;
-//
-//    @Autowired
-//    private RedisUtil redisUtil;
-//
-//    @Autowired
-//    private RedisLockUtil redisLockUtil;
-//
-//    @Autowired
-//    private RabbitMqProducer rabbitMqProducer;
-//
-//    @Autowired
-//    private IBuildLogService buildLogService;
-//
-//    @Autowired
-//    private LaserSceneObjGenerateHandler laserSceneObjGenerateHandler;
-//    @Autowired
-//    private ISceneBuildProcessLogService sceneBuildProcessLogService;
-//
-//    @Autowired
-//    private IBuildService buildService;
-//
-//    /**
-//     * 场景计算
-//     * @param channel
-//     * @param message
-//     * @throws Exception
-//     */
-//    @RabbitListener(
-//            queuesToDeclare = @Queue("${queue.modeling.modeling-call}"),
-//            concurrency = "${maxThread.modeling.modeling-call}",
-//            priority = "${mq.consumerPriority}"
-//    )
-//    public void buildSceneHandler(Channel channel, Message message) throws Exception {
-//        SysConstants.SYSTEM_BUILDING = true;
-//        long deliveryTag = message.getMessageProperties().getDeliveryTag();
-//        if (SysConstants.SYSTEM_OFFING) {
-//            SysConstants.SYSTEM_BUILDING = false;
-//            channel.basicNack(deliveryTag, true, true);
-//            log.error("服务实例:{} 正在关闭,退出构建!", SysConstants.hostName);
-//            return;
-//        }
-//
-//        if (ObjectUtils.isEmpty(message.getBody())) {
-//            SysConstants.SYSTEM_BUILDING = false;
-//            log.error("消息内容为空,退出构建,当前服务器id:{}", SysConstants.hostName);
-//            return;
-//        }
-//        String msg = new String(message.getBody(), StandardCharsets.UTF_8);
-//        BuildSceneCallMessage buildSceneMessage = JSONObject.parseObject(msg, BuildSceneCallMessage.class);
-//
-//        String messageId = message.getMessageProperties().getMessageId();
-//        if(Objects.isNull(buildSceneMessage) || StrUtil.isBlank(buildSceneMessage.getSceneNum())){
-//            log.error("消息内容错误,id:{},消息体:{}", messageId, msg);
-//            return;
-//        }
-//
-//        BuildLog buildLog = new BuildLog();
-//        log.info("场景计算开始,队列名:{},id:{},deliveryTag:{},消息体:{}", queueModelingCall, messageId,deliveryTag,msg);
-//        buildLog.setMessageId(messageId);
-//        buildLog.setContent(msg);
-//
-//        this.process(buildSceneMessage,buildLog);
-//        log.info("场景计算结束,队列名:{},id:{}", queueModelingCall, messageId);
-//
-//        //计算完毕,将当前系统构建状态改为false
-//        SysConstants.SYSTEM_BUILDING = false;
-//
-//        channel.basicAck(deliveryTag, false);
-//    }
-//
-//    public void process(BuildSceneCallMessage message,BuildLog buildLog) {
-//        //开始计时
-//        StopWatch watch = new StopWatch();
-//        watch.start();
-//
-//        String num = message.getSceneNum();
-//
-//        //发送记录计算状态为计算中
-//        this.sendCallBuildProcessLog(message, ModelingBuildStatus.CALCULATING);
-//
-//        final BuildSceneResultBean buildSceneResult = new BuildSceneResultBean();
-//        String resultQueueName = StrUtil.isNotBlank(message.getResultReceiverMqName()) ?
-//                message.getResultReceiverMqName() : queueModelingPost;
-//        buildSceneResult.setResultQueueName(resultQueueName);
-//        ModelingBuildStatus status = null;
-//        Future<ModelingBuildStatus> future = null;
-//        try {
-//            Map<String,Object> buildContext = new HashMap<>();
-//            //计算前准备
-//            preBuild(buildContext,message, buildLog);
-//            future = SysConstants.executorService.submit(() -> {
-//                try {
-//                    return buildScene(buildContext,message, buildSceneResult,buildLog);
-//                } catch (Exception e) {
-//                    log.error("服务实例:{} 构建异常:", SysConstants.hostName, e);
-//                    e.printStackTrace();
-//                    return ModelingBuildStatus.FAILED;
-//                }
-//            });
-//            status = future.get(SysConstants.modelTimeOut, TimeUnit.HOURS);
-//
-//            //结束计时
-//            watch.stop();
-//            buildLog.setDuration(watch.getTime(TimeUnit.SECONDS));
-//        } catch (TimeoutException ex) {
-//            log.error("服务实例:{} 构建异常:",SysConstants.hostName,ex);
-//            status = ModelingBuildStatus.OVERTIME;
-//            log.info("释放线程");
-//            //场景计算超时,需要中断当前执行任务,释放线程池中的任务线程,否则下个场景计算获取不到线程进行计算
-//            future.cancel(true);
-//        } catch (BuildException e){
-//            status = e.getBuildStatus();
-//        } catch(Exception e) {
-//            log.error("服务实例:{} 构建异常:", SysConstants.hostName, e);
-//            if (e.getCause() instanceof BuildException) {
-//                status = ((BuildException) e.getCause()).getBuildStatus();
-//                buildLog.setStatus(((BuildException) e.getCause()).getBuildStatus().code());
-//            } else {
-//                status = ModelingBuildStatus.FAILED;
-//            }
-//        }
-//        buildLog.setStatus(status.code());
-//        buildSceneResult.setCameraType(message.getCameraType());
-//        buildSceneResult.setBuildStatus(status);
-//        //计算后处理
-//        afterBuild(message, buildSceneResult, buildLog);
-//
-//    }
-//
-//    private ModelingBuildStatus buildScene(Map<String,Object> buildContext,BuildSceneCallMessage message, BuildSceneResultBean buildSceneResult,BuildLog logRecord) throws Exception{
-//        //如果mq生产者在消息体中设置了结算结果mq队列名,就发到这个队列,否则就发送到默认队列
-//        String path = message.getPath();
-//        String num = message.getSceneNum();
-//        //不同的相机不同的方法
-//        String cameraType = message.getCameraType();
-//        String algorithm = message.getAlgorithm();
-//        //0表示有4k图,1表示没有
-//        String resolution = message.getResolution();
-//        //判断调用V2还是V3版本的算法
-//        String buildType = ObjectUtils.isEmpty(message.getBuildType()) ? "V2" : message.getBuildType();
-//
-//        buildSceneResult.setCameraType(cameraType);
-//        buildSceneResult.setNum(num);
-//        buildSceneResult.setPath(path);
-//
-//        log.info("用的算法是:" + algorithm);
-//
-//        String dataFdagePath = path + File.separator + "capture" +File.separator+"data.fdage";
-//        log.info("dataFdagePath 文件路径 :{}", dataFdagePath);
-//        String data = FileUtils.readFile(dataFdagePath);
-//        //获取data.fdage的内容
-//        JSONObject dataJson = new JSONObject();
-//        if(data!=null){
-//            dataJson = JSONObject.parseObject(data);
-//        }
-//
-//        if (dataJson.containsKey("OnlyExportMeshObj")) {
-//            logRecord.setBuildType(2);
-//            Map<String, String> context = new HashMap<>();
-//            context.put("path", path);
-//            context.put("cameraType", cameraType);
-//            context.put("algorithm", algorithm);
-//            context.put("resolution", resolution);
-//            context.put("projectNum", num);
-//            context.put("dataJson", data);
-//            try {
-//                laserSceneObjGenerateHandler.handle(context);
-//            } catch (Exception e) {
-//                e.printStackTrace();
-//            }
-//
-//            // 检测计算结果文件是否有生成
-//            String resultsPath = path + File.separator + "results" + File.separator;
-//            if (!new File(resultsPath + "upload.json").exists()) {
-//                log.error("未检测到计算结果文件:upload.json");
-//                return ModelingBuildStatus.FAILED;
-//            }
-//
-//            return ModelingBuildStatus.SUCCESS;
-//        }
-//
-//        Map<String, String> dataMap = buildService.getTypeString(cameraType, algorithm, resolution,dataJson);
-//
-//        String splitType = dataMap.get("splitType");
-//        String skyboxType = dataMap.get("skyboxType");
-//
-//        ComputerUtil.createProjectAndDataFile(path,num, splitType, skyboxType,null,null);
-//        //计算模型并返回需要上传oss的文件集合
-//        ComputerUtil.computer(num, path, buildType);
-//
-//        // 检测计算结果文件是否有生成
-//        String resultsPath = path + File.separator + "results" + File.separator;
-//        if (!new File(resultsPath + "upload.json").exists()) {
-//            log.error("未检测到计算结果文件:upload.json");
-//            return ModelingBuildStatus.FAILED;
-//        }
-//
-//        Object linkPanTargetListObj = message.getExt().get("linkPanTargetList");
-//        if(Objects.nonNull(linkPanTargetListObj)){
-//            List<String> linkPanTargetList = (List<String>) linkPanTargetListObj;
-//            for (String target : linkPanTargetList) {
-//                CreateObjUtil.build3dModel(target,null);
-//
-//                // 检测计算结果文件是否有生成
-//                String linkPanoResultsPath = target + File.separator + "results" + File.separator;
-//                Thread.sleep(2000L);
-//                if (!new File(linkPanoResultsPath + "upload.json").exists()) {
-//                    log.error("未检测到场景关联计算结果文件:upload.json, linkPanoResultsPath:{}", linkPanoResultsPath);
-//                    return ModelingBuildStatus.FAILED;
-//                }
-//            }
-//        }
-//
-//        //平面图ai识别
-//        buildSceneResult.setDetFloorplan(this.detFloorplan(path));
-//
-//        return ModelingBuildStatus.SUCCESS;
-//    }
-//
-//    private LinkedHashMap<Integer, Boolean> detFloorplan(String path) throws Exception {
-//        LinkedHashMap<Integer, Boolean> result = new LinkedHashMap<>();
-//        String workDir = path + "/detFloorplan/";
-//        if(FileUtil.exist(workDir)){
-//            FileUtil.del(workDir);
-//        }
-//        String infoJsonPath = path + "/results/floorplan/info.json";
-//        if(!FileUtil.exist(infoJsonPath)){
-//            return result;
-//        }
-//
-//        JSONObject infoObj = JSON.parseObject(FileUtil.readUtf8String(infoJsonPath));
-//        JSONArray floors = infoObj.getJSONArray("floors");
-//        if(CollUtil.isEmpty(floors)){
-//            return result;
-//        }
-//        for (Object o : floors) {
-//            JSONObject floor = (JSONObject) o;
-//            Integer subgroup = floor.getInteger("subgroup");
-//            String detectPath = workDir + subgroup + "/detect.json";
-//            String floorKeyPath = path + "/results/floorplan/floor_" + subgroup + ".png";
-//            String parent = FileUtil.getParent(detectPath, 1);
-//            FileUtil.mkdir(parent);
-//            result.put(subgroup, false);
-//            if(!FileUtil.exist(floorKeyPath)){
-//                continue;
-//            }
-//            String cmd = CmdConstant.LAYOUT_DETECT;
-//            cmd = cmd.replace("@in", floorKeyPath);
-//            cmd = cmd.replace("@out", detectPath);
-//            CmdUtils.callLine(cmd, 50);
-//            if (ComputerUtil.checkComputeCompleted(detectPath,5, 500)) {
-//                result.put(subgroup, true);
-//            }
-//        }
-//
-//        return result;
-//    }
-//
-//    public static void main(String[] args) {
-//        File file = FileUtil.file("D:\\test\\111.txt");
-////这里只监听文件或目录的修改事件
-//        WatchMonitor watchMonitor = WatchMonitor.create(file);
-//        watchMonitor.setWatcher(new Watcher(){
-//            @Override
-//            public void onCreate(WatchEvent<?> event, Path currentPath) {
-//                Object obj = event.context();
-//                Console.log("创建:{}-> {}", currentPath, obj);
-//            }
-//
-//            @Override
-//            public void onModify(WatchEvent<?> event, Path currentPath) {
-//                Object obj = event.context();
-//                Console.log("修改:{}-> {}", currentPath, obj);
-//            }
-//
-//            @Override
-//            public void onDelete(WatchEvent<?> event, Path currentPath) {
-//                Object obj = event.context();
-//                Console.log("删除:{}-> {}", currentPath, obj);
-//            }
-//
-//            @Override
-//            public void onOverflow(WatchEvent<?> event, Path currentPath) {
-//                Object obj = event.context();
-//                Console.log("Overflow:{}-> {}", currentPath, obj);
-//            }
-//        });
-//        watchMonitor.start();
-//        for (int i= 0; i< 10; i++ ){
-//            System.out.println(i);
-//        }
-//
-//    }
-//
-//    private void afterBuild(BuildSceneCallMessage message, BuildSceneResultBean buildSceneResult, BuildLog buildLog){
-//        ModelingBuildStatus buildStatus = null;
-//        try {
-//            buildStatus = buildSceneResult.getBuildStatus();
-//            log.info("服务{} 计算结束:{},计算状态:{}", SysConstants.hostName, buildLog.getSceneNum(),buildStatus.message());
-//            //释放锁
-//            Long decr = redisUtil.decr(SysConstants.SCENE_BUILDING + buildLog.getSceneNum(), 1);
-//            if (decr.compareTo(1L) < 0) {
-//                redisUtil.del(SysConstants.SCENE_BUILDING + buildLog.getSceneNum());
-//            }
-//            buildLog.setUpdateTime(new Date());
-//            buildLog.setResultQuequeName(buildSceneResult.getResultQueueName());
-//            buildLogService.updateById(buildLog);
-//        } catch (Exception e) {
-//            log.error("计算后业务处理出错!", e);
-//        }finally {
-//            //发送计算结果mq
-//            buildSceneResult.setDuration(buildLog.getDuration());
-//            this.sendCallResult(message, buildSceneResult);
-//            this.sendCallBuildProcessLog(message, buildStatus);
-//        }
-//    }
-//
-//    /**
-//     * 发送计算流程状态日志mq
-//     * @param message
-//     * @param buildStatus
-//     */
-//    private void sendCallBuildProcessLog(BuildSceneCallMessage message, ModelingBuildStatus buildStatus){
-//        rabbitMqProducer.sendByWorkQueue(queueModelingProcessLog,
-//                BuildSceneProcessLogMessage.builder().num(message.getSceneNum()).buildStatus(buildStatus.code()).build());
-//    }
-//
-//    private void preBuild(Map<String,Object> buildContext,BuildSceneCallMessage message, BuildLog buildLog) throws BuildException {
-//
-//        // 初始化日志参数
-//        buildLog.setHostName(SysConstants.hostName);
-//        buildLog.setQueueName(queueModelingCall);
-//        buildLog.setSceneNum(message.getSceneNum());
-//        buildLog.setDataSource(message.getPath());
-//        buildLog.setCreateTime(new Date());
-//        buildLog.setUpdateTime(new Date());
-//        buildLog.setBuildType(0);
-//        buildLog.setStatus(0);
-//        // 设置缓存锁
-//        String key = SysConstants.SCENE_BUILDING + buildLog.getSceneNum();
-//        // 如果是强制重新计算,则删除key。
-//        if (StringUtils.equals(message.getRebuild(), "1")) {
-//            redisUtil.del(key);
-//        }
-//
-//        // 获取缓存锁,防止重复消费
-//        Long building = redisUtil.incr(key, 1);
-//        buildLogService.save(buildLog);
-//
-//        if(!ObjectUtils.isEmpty(buildLog.getMessageId())){
-//            // 设置消息id幂等性,防止消息重复消费
-//            boolean lock = redisLockUtil.lock(SysConstants.SCENE_MESSAGE_BUILDING + buildLog.getMessageId(), SysConstants.modelTimeOut * 3600);
-//            if (!lock) {
-//                log.error("服务:{},消息重复消费:{}", SysConstants.hostName, buildLog.getMessageId());
-//                throw new BuildException(ModelingBuildStatus.REPEAT);
-//            }
-//        }
-//
-//        if (building.compareTo(1L) > 0) {
-//            log.error("服务:{},重复构建:{},构建次数:{}", SysConstants.hostName, buildLog.getSceneNum(),building);
-//            throw new BuildException(ModelingBuildStatus.REPEAT);
-//        } else {
-//            redisUtil.expire(key, Integer.toUnsignedLong(SysConstants.modelTimeOut * 3600));
-//        }
-//    }
-//
-//    /**
-//     * 发送计算结果
-//     * @param message
-//     * @param buildSceneResult
-//     */
-//    private void sendCallResult(BuildSceneCallMessage message, BuildSceneResultBean buildSceneResult){
-//        ModelingBuildStatus buildStatus = buildSceneResult.getBuildStatus();
-//        //重复计算不需要发送mq做后置处理
-//        if(buildStatus.equals(ModelingBuildStatus.REPEAT)){
-//            return;
-//        }
-//        BuildSceneResultMqMessage buildResult = BuildSceneResultMqMessage.builder()
-//                .buildSuccess(buildStatus.equals(ModelingBuildStatus.SUCCESS))
-//                .computeTime(buildSceneResult.getDuration())
-//                .path(buildSceneResult.getPath())
-//                .hostName(SysConstants.hostName)
-//                .build();
-//        buildResult.setBuildContext(message.getBuildContext());
-//        buildResult.setExt(message.getExt());
-//        buildResult.setDetFloorplan(buildSceneResult.getDetFloorplan());
-//        rabbitMqProducer.sendByWorkQueue(buildSceneResult.getResultQueueName(),buildResult);
-//    }
-//}
+package com.fdkankan.modeling.receiver;
+
+import cn.hutool.core.collection.CollUtil;
+import cn.hutool.core.io.FileUtil;
+import cn.hutool.core.io.watch.WatchMonitor;
+import cn.hutool.core.io.watch.Watcher;
+import cn.hutool.core.lang.Console;
+import cn.hutool.core.util.ObjectUtil;
+import cn.hutool.core.util.StrUtil;
+import com.alibaba.fastjson.JSON;
+import com.alibaba.fastjson.JSONArray;
+import com.alibaba.fastjson.JSONObject;
+import com.fdkankan.common.constant.CommonOperStatus;
+import com.fdkankan.common.constant.ErrorCode;
+import com.fdkankan.common.constant.ModelingBuildStatus;
+import com.fdkankan.common.exception.BusinessException;
+import com.fdkankan.common.util.CmdUtils;
+import com.fdkankan.common.util.FileUtils;
+import com.fdkankan.model.constants.ConstantFilePath;
+import com.fdkankan.model.utils.ComputerUtil;
+import com.fdkankan.model.utils.CreateObjUtil;
+import com.fdkankan.modeling.bean.BuildSceneResultBean;
+import com.fdkankan.modeling.constants.CmdConstant;
+import com.fdkankan.modeling.constants.SysConstants;
+import com.fdkankan.modeling.entity.BuildLog;
+import com.fdkankan.modeling.exception.BuildException;
+import com.fdkankan.modeling.handler.LaserSceneObjGenerateHandler;
+import com.fdkankan.modeling.service.IBuildLogService;
+import com.fdkankan.modeling.service.IBuildService;
+import com.fdkankan.modeling.service.ISceneBuildProcessLogService;
+import com.fdkankan.rabbitmq.bean.BuildSceneCallMessage;
+import com.fdkankan.rabbitmq.bean.BuildSceneProcessLogMessage;
+import com.fdkankan.rabbitmq.bean.BuildSceneResultMqMessage;
+import com.fdkankan.rabbitmq.util.RabbitMqProducer;
+import com.fdkankan.redis.util.RedisLockUtil;
+import com.fdkankan.redis.util.RedisUtil;
+import com.rabbitmq.client.Channel;
+import com.fdkankan.model.constants.SceneBuildProcessType;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.commons.lang3.time.StopWatch;
+import org.springframework.amqp.core.Message;
+import org.springframework.amqp.rabbit.annotation.Queue;
+import org.springframework.amqp.rabbit.annotation.RabbitListener;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.stereotype.Component;
+import org.springframework.util.ObjectUtils;
+import java.io.File;
+import java.nio.charset.StandardCharsets;
+import java.nio.file.Path;
+import java.nio.file.WatchEvent;
+import java.util.*;
+import java.util.concurrent.Future;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.TimeoutException;
+
+/**
+ * <p>
+ * TODO
+ * </p>
+ *
+ * @author dengsixing
+ * @since 2022/4/20
+ **/
+@Slf4j
+@Component
+public class RabbitMqListener {
+
+    @Value("${queue.modeling.modeling-call}")
+    private String queueModelingCall;
+    @Value("${queue.modeling.modeling-post}")
+    private String queueModelingPost;
+    @Value("${queue.modeling.modeling-process-log}")
+    private String queueModelingProcessLog;
+
+    @Autowired
+    private RedisUtil redisUtil;
+
+    @Autowired
+    private RedisLockUtil redisLockUtil;
+
+    @Autowired
+    private RabbitMqProducer rabbitMqProducer;
+
+    @Autowired
+    private IBuildLogService buildLogService;
+
+    @Autowired
+    private LaserSceneObjGenerateHandler laserSceneObjGenerateHandler;
+    @Autowired
+    private ISceneBuildProcessLogService sceneBuildProcessLogService;
+
+    @Autowired
+    private IBuildService buildService;
+
+    /**
+     * 场景计算
+     * @param channel
+     * @param message
+     * @throws Exception
+     */
+    @RabbitListener(
+            queuesToDeclare = @Queue("${queue.modeling.modeling-call}"),
+            concurrency = "${maxThread.modeling.modeling-call}",
+            priority = "${mq.consumerPriority}"
+    )
+    public void buildSceneHandler(Channel channel, Message message) throws Exception {
+        SysConstants.SYSTEM_BUILDING = true;
+        long deliveryTag = message.getMessageProperties().getDeliveryTag();
+        if (SysConstants.SYSTEM_OFFING) {
+            SysConstants.SYSTEM_BUILDING = false;
+            channel.basicNack(deliveryTag, true, true);
+            log.error("服务实例:{} 正在关闭,退出构建!", SysConstants.hostName);
+            return;
+        }
+
+        if (ObjectUtils.isEmpty(message.getBody())) {
+            SysConstants.SYSTEM_BUILDING = false;
+            log.error("消息内容为空,退出构建,当前服务器id:{}", SysConstants.hostName);
+            return;
+        }
+        String msg = new String(message.getBody(), StandardCharsets.UTF_8);
+        BuildSceneCallMessage buildSceneMessage = JSONObject.parseObject(msg, BuildSceneCallMessage.class);
+
+        String messageId = message.getMessageProperties().getMessageId();
+        if(Objects.isNull(buildSceneMessage) || StrUtil.isBlank(buildSceneMessage.getSceneNum())){
+            log.error("消息内容错误,id:{},消息体:{}", messageId, msg);
+            return;
+        }
+
+        //进入计算程序前,场景已删除,就不往下跑
+        if(SysConstants.interrupCallingNums.contains(buildSceneMessage.getSceneNum())){
+            channel.basicAck(deliveryTag, false);
+        }
+
+        BuildLog buildLog = new BuildLog();
+        log.info("场景计算开始,队列名:{},id:{},deliveryTag:{},消息体:{}", queueModelingCall, messageId,deliveryTag,msg);
+        buildLog.setMessageId(messageId);
+        buildLog.setContent(msg);
+
+        this.process(buildSceneMessage,buildLog);
+        log.info("场景计算结束,队列名:{},id:{}", queueModelingCall, messageId);
+
+        //计算完毕,将当前系统构建状态改为false
+        SysConstants.SYSTEM_BUILDING = false;
+
+        channel.basicAck(deliveryTag, false);
+    }
+
+    public void process(BuildSceneCallMessage message,BuildLog buildLog) {
+        //开始计时
+        StopWatch watch = new StopWatch();
+        watch.start();
+
+        String num = message.getSceneNum();
+
+        //发送记录计算状态为计算中
+        this.sendCallBuildProcessLog(message, ModelingBuildStatus.CALCULATING);
+
+        final BuildSceneResultBean buildSceneResult = new BuildSceneResultBean();
+        String resultQueueName = StrUtil.isNotBlank(message.getResultReceiverMqName()) ?
+                message.getResultReceiverMqName() : queueModelingPost;
+        buildSceneResult.setResultQueueName(resultQueueName);
+        ModelingBuildStatus status = null;
+        Future<ModelingBuildStatus> future = null;
+        try {
+            Map<String,Object> buildContext = new HashMap<>();
+            //计算前准备
+            preBuild(buildContext,message, buildLog);
+            future = SysConstants.executorService.submit(() -> {
+                try {
+                    return buildScene(buildContext,message, buildSceneResult,buildLog);
+                } catch (Exception e) {
+                    log.error("服务实例:{} 构建异常:", SysConstants.hostName, e);
+                    return ModelingBuildStatus.FAILED;
+                }
+            });
+            status = future.get(SysConstants.modelTimeOut, TimeUnit.HOURS);
+
+            //结束计时
+            watch.stop();
+            buildLog.setDuration(watch.getTime(TimeUnit.SECONDS));
+        } catch (TimeoutException ex) {
+            log.error("服务实例:{} 构建异常:",SysConstants.hostName,ex);
+            status = ModelingBuildStatus.OVERTIME;
+            log.info("释放线程");
+            //场景计算超时,需要中断当前执行任务,释放线程池中的任务线程,否则下个场景计算获取不到线程进行计算
+            future.cancel(true);
+        } catch (BuildException e){
+            status = e.getBuildStatus();
+        } catch(Exception e) {
+            log.error("服务实例:{} 构建异常:", SysConstants.hostName, e);
+            if (e.getCause() instanceof BuildException) {
+                status = ((BuildException) e.getCause()).getBuildStatus();
+                buildLog.setStatus(((BuildException) e.getCause()).getBuildStatus().code());
+            } else {
+                status = ModelingBuildStatus.FAILED;
+            }
+        }
+        buildLog.setStatus(status.code());
+        buildSceneResult.setCameraType(message.getCameraType());
+        buildSceneResult.setBuildStatus(status);
+        //计算后处理
+
+        afterBuild(message, buildSceneResult, buildLog);
+    }
+
+    private ModelingBuildStatus buildScene(Map<String,Object> buildContext,BuildSceneCallMessage message, BuildSceneResultBean buildSceneResult,BuildLog logRecord) throws Exception{
+        //如果mq生产者在消息体中设置了结算结果mq队列名,就发到这个队列,否则就发送到默认队列
+        String path = message.getPath();
+        String num = message.getSceneNum();
+        //不同的相机不同的方法
+        String cameraType = message.getCameraType();
+        String algorithm = message.getAlgorithm();
+        //0表示有4k图,1表示没有
+        String resolution = message.getResolution();
+        //判断调用V2还是V3版本的算法
+        String buildType = ObjectUtils.isEmpty(message.getBuildType()) ? "V2" : message.getBuildType();
+
+        buildSceneResult.setCameraType(cameraType);
+        buildSceneResult.setNum(num);
+        buildSceneResult.setPath(path);
+
+        log.info("用的算法是:" + algorithm);
+
+        String dataFdagePath = path + File.separator + "capture" +File.separator+"data.fdage";
+        log.info("dataFdagePath 文件路径 :{}", dataFdagePath);
+        String data = FileUtils.readFile(dataFdagePath);
+        //获取data.fdage的内容
+        JSONObject dataJson = new JSONObject();
+        if(data!=null){
+            dataJson = JSONObject.parseObject(data);
+        }
+
+        if (dataJson.containsKey("OnlyExportMeshObj")) {
+            logRecord.setBuildType(2);
+            Map<String, String> context = new HashMap<>();
+            context.put("path", path);
+            context.put("cameraType", cameraType);
+            context.put("algorithm", algorithm);
+            context.put("resolution", resolution);
+            context.put("projectNum", num);
+            context.put("dataJson", data);
+            try {
+                laserSceneObjGenerateHandler.handle(context);
+            } catch (Exception e) {
+                e.printStackTrace();
+            }
+
+            // 检测计算结果文件是否有生成
+            String resultsPath = path + File.separator + "results" + File.separator;
+            if (!new File(resultsPath + "upload.json").exists()) {
+                log.error("未检测到计算结果文件:upload.json");
+                return ModelingBuildStatus.FAILED;
+            }
+
+            return ModelingBuildStatus.SUCCESS;
+        }
+
+        Map<String, String> dataMap = buildService.getTypeString(cameraType, algorithm, resolution,dataJson);
+
+        String splitType = dataMap.get("splitType");
+        String skyboxType = dataMap.get("skyboxType");
+
+        ComputerUtil.createProjectAndDataFile(path,num, splitType, skyboxType,null,null);
+
+        //场景已删除,不启动算法进程
+        if(SysConstants.interrupCallingNums.contains(num)){
+            throw new BusinessException(ErrorCode.APP_ID_ILLEGAL);
+        }
+
+        //计算模型并返回需要上传oss的文件集合
+        ComputerUtil.computer(num, path, buildType);
+
+        // 检测计算结果文件是否有生成
+        String resultsPath = path + File.separator + "results" + File.separator;
+        if (!new File(resultsPath + "upload.json").exists()) {
+            log.error("未检测到计算结果文件:upload.json");
+            return ModelingBuildStatus.FAILED;
+        }
+
+        Object linkPanTargetListObj = message.getExt().get("linkPanTargetList");
+        if(Objects.nonNull(linkPanTargetListObj)){
+            List<String> linkPanTargetList = (List<String>) linkPanTargetListObj;
+            for (String target : linkPanTargetList) {
+                CreateObjUtil.build3dModel(target,null);
+
+                // 检测计算结果文件是否有生成
+                String linkPanoResultsPath = target + File.separator + "results" + File.separator;
+                Thread.sleep(2000L);
+                if (!new File(linkPanoResultsPath + "upload.json").exists()) {
+                    log.error("未检测到场景关联计算结果文件:upload.json, linkPanoResultsPath:{}", linkPanoResultsPath);
+                    return ModelingBuildStatus.FAILED;
+                }
+            }
+        }
+
+        //平面图ai识别
+        buildSceneResult.setDetFloorplan(this.detFloorplan(path));
+
+        return ModelingBuildStatus.SUCCESS;
+    }
+
+    private LinkedHashMap<Integer, Boolean> detFloorplan(String path) throws Exception {
+        LinkedHashMap<Integer, Boolean> result = new LinkedHashMap<>();
+        String workDir = path + "/detFloorplan/";
+        if(FileUtil.exist(workDir)){
+            FileUtil.del(workDir);
+        }
+        String infoJsonPath = path + "/results/floorplan/info.json";
+        if(!FileUtil.exist(infoJsonPath)){
+            return result;
+        }
+
+        JSONObject infoObj = JSON.parseObject(FileUtil.readUtf8String(infoJsonPath));
+        JSONArray floors = infoObj.getJSONArray("floors");
+        if(CollUtil.isEmpty(floors)){
+            return result;
+        }
+        for (Object o : floors) {
+            JSONObject floor = (JSONObject) o;
+            Integer subgroup = floor.getInteger("subgroup");
+            String detectPath = workDir + subgroup + "/detect.json";
+            String floorKeyPath = path + "/results/floorplan/floor_" + subgroup + ".png";
+            String parent = FileUtil.getParent(detectPath, 1);
+            FileUtil.mkdir(parent);
+            result.put(subgroup, false);
+            if(!FileUtil.exist(floorKeyPath)){
+                continue;
+            }
+            String cmd = CmdConstant.LAYOUT_DETECT;
+            cmd = cmd.replace("@in", floorKeyPath);
+            cmd = cmd.replace("@out", detectPath);
+            CmdUtils.callLine(cmd, 50);
+            if (ComputerUtil.checkComputeCompleted(detectPath,5, 500)) {
+                result.put(subgroup, true);
+            }
+        }
+
+        return result;
+    }
+
+    public static void main(String[] args) {
+        File file = FileUtil.file("D:\\test\\111.txt");
+//这里只监听文件或目录的修改事件
+        WatchMonitor watchMonitor = WatchMonitor.create(file);
+        watchMonitor.setWatcher(new Watcher(){
+            @Override
+            public void onCreate(WatchEvent<?> event, Path currentPath) {
+                Object obj = event.context();
+                Console.log("创建:{}-> {}", currentPath, obj);
+            }
+
+            @Override
+            public void onModify(WatchEvent<?> event, Path currentPath) {
+                Object obj = event.context();
+                Console.log("修改:{}-> {}", currentPath, obj);
+            }
+
+            @Override
+            public void onDelete(WatchEvent<?> event, Path currentPath) {
+                Object obj = event.context();
+                Console.log("删除:{}-> {}", currentPath, obj);
+            }
+
+            @Override
+            public void onOverflow(WatchEvent<?> event, Path currentPath) {
+                Object obj = event.context();
+                Console.log("Overflow:{}-> {}", currentPath, obj);
+            }
+        });
+        watchMonitor.start();
+        for (int i= 0; i< 10; i++ ){
+            System.out.println(i);
+        }
+
+    }
+
+    private void afterBuild(BuildSceneCallMessage message, BuildSceneResultBean buildSceneResult, BuildLog buildLog){
+        ModelingBuildStatus buildStatus = null;
+        try {
+            buildStatus = buildSceneResult.getBuildStatus();
+            log.info("服务{} 计算结束:{},计算状态:{}", SysConstants.hostName, buildLog.getSceneNum(),buildStatus.message());
+            //释放锁
+            Long decr = redisUtil.decr(SysConstants.SCENE_BUILDING + buildLog.getSceneNum(), 1);
+            if (decr.compareTo(1L) < 0) {
+                redisUtil.del(SysConstants.SCENE_BUILDING + buildLog.getSceneNum());
+            }
+            buildLog.setUpdateTime(new Date());
+            buildLog.setResultQuequeName(buildSceneResult.getResultQueueName());
+            buildLogService.updateById(buildLog);
+        } catch (Exception e) {
+            log.error("计算后业务处理出错!", e);
+        }finally {
+            //发送计算结果mq
+            buildSceneResult.setDuration(buildLog.getDuration());
+            this.sendCallResult(message, buildSceneResult);
+            this.sendCallBuildProcessLog(message, buildStatus);
+        }
+    }
+
+    /**
+     * 发送计算流程状态日志mq
+     * @param message
+     * @param buildStatus
+     */
+    private void sendCallBuildProcessLog(BuildSceneCallMessage message, ModelingBuildStatus buildStatus){
+        rabbitMqProducer.sendByWorkQueue(queueModelingProcessLog,
+                BuildSceneProcessLogMessage.builder().num(message.getSceneNum()).buildStatus(buildStatus.code()).build());
+    }
+
+    private void preBuild(Map<String,Object> buildContext,BuildSceneCallMessage message, BuildLog buildLog) throws BuildException {
+
+        // 初始化日志参数
+        buildLog.setHostName(SysConstants.hostName);
+        buildLog.setQueueName(queueModelingCall);
+        buildLog.setSceneNum(message.getSceneNum());
+        buildLog.setDataSource(message.getPath());
+        buildLog.setCreateTime(new Date());
+        buildLog.setUpdateTime(new Date());
+        buildLog.setBuildType(0);
+        buildLog.setStatus(0);
+        // 设置缓存锁
+        String key = SysConstants.SCENE_BUILDING + buildLog.getSceneNum();
+        // 如果是强制重新计算,则删除key。
+        if (StringUtils.equals(message.getRebuild(), "1")) {
+            redisUtil.del(key);
+        }
+
+        // 获取缓存锁,防止重复消费
+        Long building = redisUtil.incr(key, 1);
+        buildLogService.save(buildLog);
+
+        if(!ObjectUtils.isEmpty(buildLog.getMessageId())){
+            // 设置消息id幂等性,防止消息重复消费
+            boolean lock = redisLockUtil.lock(SysConstants.SCENE_MESSAGE_BUILDING + buildLog.getMessageId(), SysConstants.modelTimeOut * 3600);
+            if (!lock) {
+                log.error("服务:{},消息重复消费:{}", SysConstants.hostName, buildLog.getMessageId());
+                throw new BuildException(ModelingBuildStatus.REPEAT);
+            }
+        }
+
+        if (building.compareTo(1L) > 0) {
+            log.error("服务:{},重复构建:{},构建次数:{}", SysConstants.hostName, buildLog.getSceneNum(),building);
+            throw new BuildException(ModelingBuildStatus.REPEAT);
+        } else {
+            redisUtil.expire(key, Integer.toUnsignedLong(SysConstants.modelTimeOut * 3600));
+        }
+    }
+
+    /**
+     * 发送计算结果
+     * @param message
+     * @param buildSceneResult
+     */
+    private void sendCallResult(BuildSceneCallMessage message, BuildSceneResultBean buildSceneResult){
+        ModelingBuildStatus buildStatus = buildSceneResult.getBuildStatus();
+        //重复计算不需要发送mq做后置处理
+        if(buildStatus.equals(ModelingBuildStatus.REPEAT)){
+            return;
+        }
+        BuildSceneResultMqMessage buildResult = BuildSceneResultMqMessage.builder()
+                .buildSuccess(buildStatus.equals(ModelingBuildStatus.SUCCESS))
+                .computeTime(buildSceneResult.getDuration())
+                .path(buildSceneResult.getPath())
+                .hostName(SysConstants.hostName)
+                .build();
+        buildResult.setBuildContext(message.getBuildContext());
+        buildResult.setExt(message.getExt());
+        buildResult.setDetFloorplan(buildSceneResult.getDetFloorplan());
+        rabbitMqProducer.sendByWorkQueue(buildSceneResult.getResultQueueName(),buildResult);
+    }
+}