xiewj 4 mēneši atpakaļ
vecāks
revīzija
707d4f4ef5
36 mainītis faili ar 3806 papildinājumiem un 0 dzēšanām
  1. 16 0
      720yun_fd_consumer/src/main/java/com/gis/ConsumerApplication.java
  2. 52 0
      720yun_fd_consumer/src/main/java/com/gis/ConsumerApplicationRunner.java
  3. 29 0
      720yun_fd_consumer/src/main/java/com/gis/constant/NavigationTypeEnum.java
  4. 107 0
      720yun_fd_consumer/src/main/java/com/gis/constant/RabbitConfig.java
  5. 6 0
      720yun_fd_consumer/src/main/java/com/gis/constant/RedisKey.java
  6. 37 0
      720yun_fd_consumer/src/main/java/com/gis/constant/StorageType.java
  7. 106 0
      720yun_fd_consumer/src/main/java/com/gis/constant/SysConstants.java
  8. 41 0
      720yun_fd_consumer/src/main/java/com/gis/controller/TestController.java
  9. 93 0
      720yun_fd_consumer/src/main/java/com/gis/exception/BaseRuntimeException.java
  10. 66 0
      720yun_fd_consumer/src/main/java/com/gis/listener/DoSliceListener.java
  11. 677 0
      720yun_fd_consumer/src/main/java/com/gis/listener/SceneListener.java
  12. 92 0
      720yun_fd_consumer/src/main/java/com/gis/listener/SceneMigrateListener.java
  13. 80 0
      720yun_fd_consumer/src/main/java/com/gis/listener/ScenePayStatusListener.java
  14. 49 0
      720yun_fd_consumer/src/main/java/com/gis/listener/container/DoSliceQueueListener.java
  15. 63 0
      720yun_fd_consumer/src/main/java/com/gis/listener/container/PanoMigrateSceneQueueListener.java
  16. 67 0
      720yun_fd_consumer/src/main/java/com/gis/listener/container/PanoPayStatusSceneQueueListener.java
  17. 141 0
      720yun_fd_consumer/src/main/java/com/gis/listener/container/RabbitMQConfig.java
  18. 203 0
      720yun_fd_consumer/src/main/java/com/gis/listener/container/SceneQueueListener.java
  19. 592 0
      720yun_fd_consumer/src/main/java/com/gis/listener/container/SceneWorkQueueListener.java
  20. 45 0
      720yun_fd_consumer/src/main/java/com/gis/receiver/QueueNameService.java
  21. 63 0
      720yun_fd_consumer/src/main/resources/application-dev.yml
  22. 87 0
      720yun_fd_consumer/src/main/resources/application-loc-site.yml
  23. 63 0
      720yun_fd_consumer/src/main/resources/application-loc.yml
  24. 56 0
      720yun_fd_consumer/src/main/resources/application-locSitAws.yml
  25. 75 0
      720yun_fd_consumer/src/main/resources/application-locsitSD.yml
  26. 89 0
      720yun_fd_consumer/src/main/resources/application-pro.yml
  27. 89 0
      720yun_fd_consumer/src/main/resources/application-proAws.yml
  28. 59 0
      720yun_fd_consumer/src/main/resources/application-proSD.yml
  29. 89 0
      720yun_fd_consumer/src/main/resources/application-sit.yml
  30. 85 0
      720yun_fd_consumer/src/main/resources/application-sitAws.yml
  31. 76 0
      720yun_fd_consumer/src/main/resources/application-sitSD.yml
  32. 43 0
      720yun_fd_consumer/src/main/resources/application.yml
  33. 105 0
      720yun_fd_consumer/src/main/resources/data/someData.json
  34. 24 0
      720yun_fd_consumer/src/main/resources/data/someDataSceneData.json
  35. 78 0
      720yun_fd_consumer/src/main/resources/data/tour.xml
  36. 163 0
      720yun_fd_consumer/src/main/resources/logback-spring.xml

+ 16 - 0
720yun_fd_consumer/src/main/java/com/gis/ConsumerApplication.java

@@ -0,0 +1,16 @@
+package com.gis;
+
+import com.github.pagehelper.autoconfigure.PageHelperAutoConfiguration;
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
+
+
+@SpringBootApplication(exclude = {DataSourceAutoConfiguration.class, PageHelperAutoConfiguration.class})
+public class ConsumerApplication {
+
+    public static void main(String[] args) {
+        SpringApplication.run(ConsumerApplication.class, args);
+    }
+
+}

+ 52 - 0
720yun_fd_consumer/src/main/java/com/gis/ConsumerApplicationRunner.java

@@ -0,0 +1,52 @@
+//package com.gis;
+//
+//import cn.hutool.core.io.FileUtil;
+//import cn.hutool.core.util.ObjUtil;
+//import cn.hutool.core.util.StrUtil;
+//import cn.hutool.extra.spring.SpringUtil;
+//import com.gis.entity.MqEcs;
+//import com.gis.service.IMqEcsService;
+//import com.gis.service.impl.MqEcsServiceImpl;
+//import lombok.extern.slf4j.Slf4j;
+//import org.springframework.beans.factory.annotation.Autowired;
+//import org.springframework.beans.factory.annotation.Value;
+//import org.springframework.boot.CommandLineRunner;
+//
+///**
+// * @author Xiewj
+// * @date 2025/3/18
+// */
+//@Slf4j
+//
+//public class ConsumerApplicationRunner  implements CommandLineRunner {
+//
+//    @Value("${mq.listener.dynamic}")
+//    public  boolean dynamic;
+//
+//
+//
+//    @Override
+//    public void run(String... args) throws Exception {
+//        if (dynamic){
+//            log.info("动态弹性启动");
+//            String host="/opt/hosts/hosts.txt";
+//            String ecs_name = FileUtil.readString(host, "UTF-8");
+//            if (StrUtil.isNotEmpty(ecs_name)){
+//                IMqEcsService mqEcsService = SpringUtil.getBean(IMqEcsService.class);
+//                MqEcs lastEcs = mqEcsService.getLastEcs();
+//                if (ObjUtil.isNotEmpty(lastEcs)){
+//                    lastEcs.setEcsName(ecs_name);
+//                    boolean b = mqEcsService.updateMqEcs(lastEcs);
+//                    if (b){
+//                        log.info("更新成功");
+//                    }
+//                }
+//            }
+//
+//
+//        }else {
+//            log.info("正常启动");
+//
+//        }
+//    }
+//}

+ 29 - 0
720yun_fd_consumer/src/main/java/com/gis/constant/NavigationTypeEnum.java

@@ -0,0 +1,29 @@
+package com.gis.constant;
+
+/**
+ * 切图方式
+ */
+public enum NavigationTypeEnum {
+
+    GROUP("group", "分组"),
+    PANO("pano", "全景图"),
+    FDKK("4dkk", "官网场景"),
+    ;
+
+    private String code;
+    private String message;
+
+    private NavigationTypeEnum(String code, String message) {
+        this.code = code;
+        this.message = message;
+    }
+
+    public String code() {
+        return code;
+    }
+
+    public String message() {
+        return message;
+    }
+
+}

+ 107 - 0
720yun_fd_consumer/src/main/java/com/gis/constant/RabbitConfig.java

@@ -0,0 +1,107 @@
+//package com.gis.constant;
+//
+//import org.springframework.amqp.core.*;
+//import org.springframework.amqp.rabbit.config.SimpleRabbitListenerContainerFactory;
+//import org.springframework.amqp.rabbit.connection.CachingConnectionFactory;
+//import org.springframework.amqp.rabbit.connection.ConnectionFactory;
+//import org.springframework.amqp.rabbit.core.RabbitTemplate;
+//import org.springframework.beans.factory.annotation.Value;
+//import org.springframework.beans.factory.config.ConfigurableBeanFactory;
+//import org.springframework.context.annotation.Bean;
+//import org.springframework.context.annotation.Configuration;
+//import org.springframework.context.annotation.Scope;
+//
+///**
+// * 即时队列
+// */
+//
+//@Configuration
+//public class RabbitConfig {
+//
+//    @Value("${spring.rabbitmq.address}")
+//    private String address;
+//
+//    @Value("${spring.rabbitmq.username}")
+//    private String username;
+//
+//    @Value("${spring.rabbitmq.password}")
+//    private String password;
+//
+//
+//
+//
+//    /** 全景图队列*/
+//    public static final String PANO_QUEUE = "720FdQueue";
+//
+//    /** 全景图交换机*/
+//    public static final String PANO_EXCHANGE = "720FdExchange";
+//
+//    /** 全景图交换机路由*/
+//    public static final String PANO_QUEUE_ROUTING = "720FdQueueRouting";
+//
+//
+//    public static final String PANO_SCENE_QUEUE = "PanoSceneQueue";
+//    public static final String PANO_SCENE_QUEUE_EXCHANGE = "PanoSceneQueueExchange";
+//
+//
+//
+//    /**
+//     * 全景图模型队列
+//     */
+//    @Bean
+//    public Queue panoQueue() {
+//        return new Queue(PANO_QUEUE);
+//    }
+//
+//    /**
+//     * 全景图交换机
+//     */
+//    @Bean
+//    public Exchange panoExchange(){
+//        return new DirectExchange(PANO_EXCHANGE, true, false);
+//    }
+//
+//
+//
+//
+//
+//    /**
+//     * 全景图队列绑定交换机
+//     */
+//    @Bean
+//    public Binding panoQueueExchange(Queue panoQueue, Exchange panoExchange){
+//        return BindingBuilder.bind(panoQueue).to(panoExchange).with(PANO_QUEUE_ROUTING).noargs();
+//    }
+//
+//
+//    /**
+//     * 以下三个方法是配置集群
+//     * @return
+//     */
+//    @Bean
+//    public SimpleRabbitListenerContainerFactory rabbitListenerContainerFactory() {
+//        SimpleRabbitListenerContainerFactory factory = new SimpleRabbitListenerContainerFactory();
+//        factory.setConnectionFactory(connectionFactory());
+//        factory.setPrefetchCount(1);
+//        return factory;
+//    }
+//
+//    @Bean
+//    public ConnectionFactory connectionFactory() {
+//        CachingConnectionFactory connectionFactory = new CachingConnectionFactory();
+//        connectionFactory.setAddresses(address);
+//        connectionFactory.setUsername(username);
+//        connectionFactory.setPassword(password);
+//        connectionFactory.setVirtualHost("/");
+//        connectionFactory.setPublisherConfirms(true);
+//        return connectionFactory;
+//    }
+//
+//    @Bean
+//    @Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
+//    public RabbitTemplate rabbitTemplate() {
+//        return new RabbitTemplate(connectionFactory());
+//    }
+//
+//
+//}

+ 6 - 0
720yun_fd_consumer/src/main/java/com/gis/constant/RedisKey.java

@@ -0,0 +1,6 @@
+package com.gis.constant;
+
+public class RedisKey {
+    public static String modelingKey = "4dkankan:modeling:scaling:hostname:%s";
+    public static String ecsStopKey = "4dkankan:modeling:scaling:hostname:stop:%s";
+}

+ 37 - 0
720yun_fd_consumer/src/main/java/com/gis/constant/StorageType.java

@@ -0,0 +1,37 @@
+package com.gis.constant;
+
+public enum StorageType {
+
+    OSS("oss", "阿里云"),
+    AWS("aws", "亚马逊"),
+    LOCAL("local", "本地");
+
+    private String code;
+    private String message;
+
+    private StorageType(String code, String message) {
+        this.code = code;
+        this.message = message;
+    }
+
+    public String code() {
+        return code;
+    }
+
+    public String message() {
+        return message;
+    }
+
+    public static StorageType get(String code){
+        StorageType[] values = StorageType.values();
+        String enumValue = null;
+        for(StorageType eachValue : values){
+            enumValue = eachValue.code();
+            if(enumValue.equals(code)){
+                return eachValue;
+            }
+        }
+        return null;
+    }
+
+}

+ 106 - 0
720yun_fd_consumer/src/main/java/com/gis/constant/SysConstants.java

@@ -0,0 +1,106 @@
+package com.gis.constant;
+
+import cn.hutool.core.io.FileUtil;
+import cn.hutool.core.util.ObjUtil;
+import com.gis.domain.entity.MqEcs;
+import com.gis.service.IMqEcsService;
+import lombok.extern.slf4j.Slf4j;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.BeansException;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.context.ApplicationContext;
+import org.springframework.context.ApplicationContextAware;
+import org.springframework.context.annotation.Conditional;
+import org.springframework.core.env.MapPropertySource;
+import org.springframework.core.env.StandardEnvironment;
+import org.springframework.stereotype.Component;
+import org.springframework.util.ObjectUtils;
+import org.springframework.util.StringUtils;
+
+import java.util.Date;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+
+@Component
+@Slf4j
+public class SysConstants implements ApplicationContextAware {
+    public static String hostName;
+    public static int modelTimeOut;
+
+    @Value("${mq.listener.dynamic}")
+    public static boolean dynamic;
+
+    @Value("${hostName.filePath:/opt/hosts/hosts.txt}")
+    public void setHostName(String filePath){
+        try {
+            if (FileUtil.exist(filePath)){
+                SysConstants.hostName = FileUtil.readUtf8String(filePath);
+                // 去除空格
+                if(!ObjectUtils.isEmpty(SysConstants.hostName)){
+                    SysConstants.hostName = SysConstants.hostName.trim().replaceAll("\\s","");
+                }
+                log.error("从文件({})中获取服务器名称:{}", filePath,hostName);
+                String queueName = initIsResidenceService();
+                log.info("initIsResidenceService--hostName:{},queueName:{}",SysConstants.hostName,queueName);
+            }else {
+                SysConstants.hostName ="";
+            }
+
+        } catch (Exception e) {
+            log.error("从文件中获取服务器名称失败,文件路径{}", filePath);
+            e.printStackTrace();
+        }
+    }
+
+    /**
+     * 默认超时时间2天
+     * @param timeOut
+     */
+    @Value("${model.timeOut:48}")
+    public void setModelTimeOut(int timeOut){
+        SysConstants.modelTimeOut = timeOut;
+    }
+
+    @Autowired
+    IMqEcsService mqEcsService;
+
+    @Value("${queue.scene-queue-work}")
+    private String queueNameDf;
+
+
+    public String initIsResidenceService() {
+        if(StringUtils.isEmpty(SysConstants.hostName)){
+            return queueNameDf;
+        }
+        MqEcs mqEcs = mqEcsService.getByHostName(SysConstants.hostName);
+        if(mqEcs == null){
+            mqEcs = mqEcsService.getLastEcs();
+            if (ObjUtil.isNull(mqEcs)){
+                log.info("获取LastEcs为空,返回默认监听队列-{}",queueNameDf);
+                return queueNameDf;
+            }
+            mqEcs.setEcsName(SysConstants.hostName);
+            mqEcs.setUpdateTime(new Date());
+            mqEcsService.updateById(mqEcs);
+        }
+        return mqEcs.getQueueName();
+    }
+
+    @Override
+    public void setApplicationContext(ApplicationContext context) throws BeansException {
+        Map<String,Object> params = new HashMap<>();
+        if (dynamic) {
+            params.put("mq.consumerPriority",1);
+
+        } else {
+            params.put("mq.consumerPriority",0);
+        }
+        ((StandardEnvironment)context.getEnvironment()).getPropertySources()
+                .addLast(new MapPropertySource("mq.consumerPriority",params));
+    }
+}

+ 41 - 0
720yun_fd_consumer/src/main/java/com/gis/controller/TestController.java

@@ -0,0 +1,41 @@
+package com.gis.controller;
+
+import com.gis.common.util.Result;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.scheduling.annotation.Async;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+/**
+ * Created by owen on 2021/1/13 0013 14:45
+ */
+@Slf4j
+@RestController
+@RequestMapping("aa")
+public class TestController {
+
+
+    @GetMapping("bb")
+    private Result addHouse(){
+        log.info("run addHouse");
+        test();
+
+        return Result.success();
+
+    }
+
+    @Async("taskExecutor")
+    public void test(){
+
+        try {
+            log.info("start");
+            Thread.sleep(5000);
+            log.info("end");
+        } catch (InterruptedException e) {
+            e.printStackTrace();
+        }
+    }
+
+
+}

+ 93 - 0
720yun_fd_consumer/src/main/java/com/gis/exception/BaseRuntimeException.java

@@ -0,0 +1,93 @@
+package com.gis.exception;
+
+import cn.hutool.core.util.StrUtil;
+import org.springframework.util.CollectionUtils;
+
+import java.util.List;
+
+public class BaseRuntimeException extends RuntimeException{
+
+    private static final long serialVersionUID = -1518945670203783450L;
+    private Integer code;
+    private String msg;
+
+    public BaseRuntimeException(String msg){
+        super(msg);
+        this.code = -1;
+        this.msg = msg;
+    }
+
+    /**
+     *
+     * @param code 允许为null
+     * @param msg
+     */
+    public BaseRuntimeException(Integer code, String msg){
+        super(msg);
+        this.code = code == null? -1 : code;
+        this.msg = msg;
+    }
+
+
+    public Integer getCode() {
+        return code;
+    }
+
+    public void setCode(Integer code) {
+        this.code = code;
+    }
+
+    public String getMsg() {
+        return msg;
+    }
+
+    public void setMsg(String msg) {
+        this.msg = msg;
+    }
+
+
+    public static void isNull(Object obj, Integer code, String msg){
+        if (obj == null){
+            getExc(code, msg);
+        }
+    }
+
+    public static void isBlank(Object obj, Integer code, String msg){
+        if (obj == null){
+            getExc(code, msg);
+        }
+
+        if (obj instanceof String && StrUtil.isBlank(obj.toString())){
+            getExc(code, msg);
+        }
+
+    }
+
+
+
+
+    /**
+     *
+     * @param obj 存在抛异常
+     * @param code 允许为null
+     * @param msg
+     */
+    public static void isTrue(boolean obj, Integer code, String msg){
+        if (obj){
+            getExc(code, msg);
+        }
+    }
+
+    public static void  getExc(Integer code, String msg){
+        throw new BaseRuntimeException(code, msg);
+    }
+
+
+
+    public static void isEmpty(List obj, Integer code, String msg){
+        if (CollectionUtils.isEmpty(obj)){
+            getExc(code, msg);
+        }
+    }
+
+}

+ 66 - 0
720yun_fd_consumer/src/main/java/com/gis/listener/DoSliceListener.java

@@ -0,0 +1,66 @@
+//package com.gis.listener;
+//
+//import com.alibaba.fastjson.JSONObject;
+//import com.gis.dto.DoSliceDTO;
+//import com.gis.service.FodderService;
+//import com.rabbitmq.client.Channel;
+//import lombok.extern.slf4j.Slf4j;
+//import org.slf4j.MDC;
+//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.context.annotation.Conditional;
+//import org.springframework.stereotype.Component;
+//import org.springframework.util.ObjectUtils;
+//
+//import java.io.IOException;
+//import java.nio.charset.StandardCharsets;
+//
+///**
+// * 消息监听器
+// *
+// * @author Xiewj
+// * @version 1.0
+// * @since 2023/08/07
+// */
+//@Component
+//@Slf4j
+//public class DoSliceListener {
+//    @Autowired
+//    FodderService fodderService;
+//
+//    /**
+//     * 全景场景初始化方法
+//     *
+//     * @param channel
+//     * @param message
+//     * @throws Exception the io exception  这里异常需要处理
+//     */
+//    @RabbitListener(
+//            queuesToDeclare = @Queue("${queue.do-slice-queue}"),concurrency = "2"
+//    )
+//    @Conditional(NonDynamicListenerCondition.class)
+//    public void doSliceQueue(Channel channel, Message message) throws IOException {
+//        if (ObjectUtils.isEmpty(message.getBody())) {
+//            log.error("消息内容为空,退出构建,当前服务器id:{}" );
+//            return;
+//        }
+//        String traceId = System.currentTimeMillis()+"";
+//        MDC.put("TRACE_ID", traceId);
+//        long deliveryTag = message.getMessageProperties().getDeliveryTag();
+//        try {
+//            String msg = new String(message.getBody(), StandardCharsets.UTF_8);
+//            String messageId = message.getMessageProperties().getMessageId();
+//            log.info("场景doSliceQueue开始,id:{},deliveryTag:{},消息体:{}", messageId,deliveryTag,msg);
+//            DoSliceDTO dto = JSONObject.parseObject(msg, DoSliceDTO.class);
+//            fodderService.doSlice(dto.getId(), traceId);
+//            channel.basicAck(deliveryTag, false);
+//        }catch (Exception e){
+//            e.printStackTrace();
+//            channel.basicAck(deliveryTag, false);
+//            log.error("场景doSliceQueue报错{}",e.getMessage());
+//        }
+//
+//    }
+//}

+ 677 - 0
720yun_fd_consumer/src/main/java/com/gis/listener/SceneListener.java

@@ -0,0 +1,677 @@
+//package com.gis.listener;
+//
+//import cn.hutool.core.bean.BeanUtil;
+//import cn.hutool.core.collection.CollUtil;
+//import cn.hutool.core.io.FileUtil;
+//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.filestorage.FileStorageTemplate;
+//import com.gis.constant.CmdConstant;
+//import com.gis.constant.ConfigConstant;
+//import com.gis.constant.SysConstants;
+//import com.gis.dto.*;
+//import com.gis.entity.*;
+//import com.gis.exception.BaseRuntimeException;
+//import com.gis.mq.RabbitMqProducerUtil;
+//import com.gis.oss.util.FileAndOssUtil;
+//import com.gis.receiver.QueueNameService;
+//import com.gis.service.*;
+//import com.gis.util.CmdUtils;
+//import com.gis.util.QrCodeUtils;
+//import com.gis.util.RandomUtils;
+//import com.rabbitmq.client.Channel;
+//import lombok.extern.slf4j.Slf4j;
+//import org.slf4j.MDC;
+//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.context.annotation.Conditional;
+//import org.springframework.stereotype.Component;
+//import org.springframework.util.ObjectUtils;
+//
+//import javax.annotation.Resource;
+//import java.io.File;
+//import java.io.PrintWriter;
+//import java.io.StringWriter;
+//import java.nio.charset.StandardCharsets;
+//import java.util.*;
+//import java.util.concurrent.*;
+//import java.util.concurrent.atomic.AtomicInteger;
+//import java.util.regex.Matcher;
+//import java.util.regex.Pattern;
+//
+///**
+// * 消息监听器
+// *
+// * @author Xiewj
+// * @version 1.0
+// * @since 2023/08/07
+// */
+//@Component
+//@Slf4j
+//public class SceneListener {
+//    @Autowired
+//    FileAndOssUtil fileAndOssUtil;
+//    @Autowired
+//    ConfigConstant configConstant;
+//    @Autowired
+//    WorkService workService;
+//    @Autowired
+//    QrCodeUtils qrCodeUtils;
+//    @Autowired
+//    ScenePanoService scenePanoService;
+//    @Autowired
+//    RabbitMqProducerUtil rabbitMqProducerUtil;
+//    @Value("${queue.relics-init-queue}")
+//    String relicsInitQueue;
+//
+//    @Value("${queue.scene-queue-work}")
+//    String sceneQueueWork;
+//    @Resource
+//    private FileStorageTemplate ossUtil;
+//
+//    @Value("${domain.4dkk}")
+//    public  String domain4dKK;
+//
+//    @Autowired
+//    private WorkNavigationSettingService workNavigationSettingService;
+//    @Autowired
+//    private WorkNavigationService workNavigationService;
+//    @Autowired
+//    private WorkCustomMaskService workCustomMaskService;
+//    @Autowired
+//    private WorkCustomButtonService workCustomButtonService;
+//
+//    @Autowired
+//    WorkCoverTypeService workCoverTypeService;
+//
+//    @Autowired
+//    WorkLogoService workLogoService;
+//
+//    @Autowired
+//    WorkOpeningTipService workOpeningTipService;
+//
+//    @Autowired
+//    WorkOpeningAnimationService workOpeningAnimationService;
+//
+//    @Autowired
+//    QueueNameService queueNameService;
+//    /**
+//     * 全景场景初始化方法
+//     *
+//     * @param channel
+//     * @param message
+//     * @throws Exception the io exception  这里异常需要处理
+//     */
+//    @RabbitListener(
+//            queuesToDeclare = @Queue("${queue.scene-queue}"),concurrency = "2"
+//    )
+//    @Conditional(NonDynamicListenerCondition.class)
+//    public void sceneQueue(Channel channel, Message message) throws Exception {
+//            if (ObjectUtils.isEmpty(message.getBody())) {
+//                log.error("消息内容为空,退出构建,当前服务器id:{}" );
+//                return;
+//            }
+//        String traceId = System.currentTimeMillis()+"";
+//        MDC.put("TRACE_ID", traceId);
+//        String sceneCode="";
+//        long deliveryTag = message.getMessageProperties().getDeliveryTag();
+//        try {
+//            String msg = new String(message.getBody(), StandardCharsets.UTF_8);
+//            String messageId = message.getMessageProperties().getMessageId();
+//            log.info("场景sceneQueue开始,id:{},deliveryTag:{},消息体:{}", messageId,deliveryTag,msg);
+//            SceneQueueDTO param = JSONObject.parseObject(msg, SceneQueueDTO.class);
+//            if (ObjectUtil.isEmpty(param.getSceneCode())) {
+//                log.error("参数列表错误(缺少),格式不匹配,{}",param);
+//                channel.basicAck(deliveryTag, false);
+//            }
+//            sceneCode=param.getSceneCode();
+//            WorkEntity workEntity=workService.findByNum(param.getSceneCode());
+//            if (ObjectUtil.isEmpty(workEntity)&&param.getStatus()==0){
+//                //初始化创建work表数据
+//                workService.entityAdd(param);
+//                sendStartMq(param);
+//                channel.basicAck(deliveryTag, false);
+//            }if (ObjectUtil.isNotEmpty(workEntity)&&param.getStatus()!=1){
+//                //修改状态
+//                workEntity.setCalcStatus(param.getStatus());
+//                if (ObjectUtil.isNotEmpty(param.getPwd())&&ObjectUtil.isEmpty(workEntity.getPassword())){
+//                    workEntity.setPassword(param.getPwd());
+//                    workEntity.setIsPassword(1);
+//                }
+//                if (ObjectUtil.isNotEmpty(param.getPayStatus())){
+//                    workEntity.setPayStatus(param.getPayStatus());
+//                }
+//                workService.updateById(workEntity);
+//                sendStartMq(param);
+//                channel.basicAck(deliveryTag, false);
+//            }else if (ObjectUtil.isNotEmpty(param.getSceneCode())&&param.getStatus()==1) {
+//                //发送到处理队列
+//                rabbitMqProducerUtil.sendByWorkQueue(sceneQueueWork, msg);
+//                channel.basicAck(deliveryTag, false);
+//
+//            }
+//
+//
+//        }catch (Exception e){
+//            if (StrUtil.isNotEmpty(sceneCode)){
+//                updateOssStatusJson(sceneCode,0);
+//            }
+//            channel.basicAck(deliveryTag, false);
+//            log.error("场景sceneQueue报错{}",e.getMessage());
+//            e.printStackTrace();
+//
+//        }
+//    }
+//
+//
+//    /**
+//     * 全景场景计算方法
+//     *
+//     * @param channel
+//     * @param message
+//     * @throws Exception the io exception  这里异常需要处理
+//     */
+//    @RabbitListener(
+//            queuesToDeclare = @Queue("#{queueNameService.getQueueName()}"),
+//            concurrency = "1",
+//            priority = "${mq.consumerPriority}"
+//    )
+//    @Conditional(DynamicListenerCondition.class)
+//    public void sceneQueueWork(Channel channel, Message message) throws Exception {
+//        if (ObjectUtils.isEmpty(message.getBody())) {
+//            log.error("消息内容为空,退出构建,当前服务器id:{}" );
+//            return;
+//        }
+//        String traceId = System.currentTimeMillis()+"";
+//        MDC.put("TRACE_ID", traceId);
+//        String sceneCode="";
+//        long deliveryTag = message.getMessageProperties().getDeliveryTag();
+//        try {
+//            String msg = new String(message.getBody(), StandardCharsets.UTF_8);
+//            String messageId = message.getMessageProperties().getMessageId();
+//            log.error("服务实例:{} 正在构建!", SysConstants.hostName);
+//            log.info("场景sceneQueueWork开始,队列名:{},id:{},deliveryTag:{},消息体:{}", queueNameService.getQueueName(), messageId,deliveryTag,msg);
+//            SceneQueueDTO param = JSONObject.parseObject(JSON.parse(msg).toString(), SceneQueueDTO.class);
+//            if (ObjectUtil.isEmpty(param.getSceneCode())) {
+//                log.error("参数列表错误(缺少),格式不匹配,{}",param);
+//                channel.basicAck(deliveryTag, false);
+//            }
+//            sceneCode=param.getSceneCode();
+//            WorkEntity workEntity=workService.findByNum(param.getSceneCode());
+//            if (ObjectUtil.isNotEmpty(param.getSceneCode())&&param.getStatus()==1){
+//                updateOssStatusJson(param.getSceneCode(),0);
+//
+//                //计算完成处理
+//                //1,下载场景的全景图 默认 。scene_view_data/panorama/目录下的全景图图片
+//                workEntity.setAlgorithmTime(param.getAlgorithmTime());
+//                workEntity.setCalcStatus(0);
+//                if (ObjectUtil.isNotEmpty(param.getPayStatus())){
+//                    workEntity.setPayStatus(param.getPayStatus());
+//                }
+//                if (ObjectUtil.isNotEmpty(param.getSceneSource())){
+//                    workEntity.setSceneSource(param.getSceneSource());
+//                }
+//                if (ObjectUtil.isNotEmpty(param.getPwd())&&ObjectUtil.isEmpty(workEntity.getPassword())){
+//                    workEntity.setPassword(param.getPwd());
+//                    workEntity.setIsPassword(1);
+//                }
+//                workService.updateById(workEntity);
+//                //清理旧数据
+//                List<ScenePanoEntity> list = scenePanoService.findByWorkId(workEntity.getId());
+//                for (ScenePanoEntity scenePanoEntity : list) {
+//                    scenePanoEntity.setIsDelete(1);
+//                    scenePanoEntity.setUpdateTime(new Date());
+//                    scenePanoService.updateById(scenePanoEntity);
+//                }
+//                String visionOssKey="scene_view_data/"+param.getSceneCode()+"/images/vision.txt";
+//
+//                JSONArray sweepLocations = new JSONArray();
+//                if (ossUtil.doesObjectExist("4dkankan",visionOssKey)){
+//                    log.info("vision.txt存在: {}",visionOssKey);
+//                    JSONObject visJson = JSONObject.parseObject(ossUtil.getFileContent("4dkankan",visionOssKey));
+//                    if(visJson.containsKey("sweepLocations")){
+//                        sweepLocations = visJson.getJSONArray("sweepLocations");
+//                    }
+//                }
+//
+//                //2,使用krpano工具生成全景图数据
+//                List<InitWorkNavigationSceneDTO> scenes = new ArrayList<>();
+//
+//                for (int i = 0; i < sweepLocations.size(); i++) {
+//                    JSONObject jsonObject = sweepLocations.getJSONObject(i);
+//                    String uuid = jsonObject.getString("uuid");
+//                    String id = jsonObject.getString("id");
+//                    String ossKey="scene_view_data/"+param.getSceneCode()+"/images/panoramas/"+uuid+".jpg";
+//                    InitWorkNavigationSceneDTO scene=new InitWorkNavigationSceneDTO();
+//                    ScenePanoEntity scenePanoEntity = this.doSlice(traceId ,ossKey, param.getSceneCode(), workEntity.getId(),uuid+".jpg",uuid,id);
+//                    //  "icon": "https://ossxiaoan.4dage.com/720yun_fd_manage/fd720_8nRkFlzpp/vtour/panos/fd720_8nRkFlzpp.tiles/thumb.jpg",
+//                    //   "sceneCode": "fd720_8nRkFlzpp",
+//                    // "sceneTitle": "0",
+//                    //  "category": 1,
+//                    //   "type": "pano",
+//                    //  "id": "s_xId8vevp",
+//                    scene.setIcon(scenePanoEntity.getIcon());
+//                    scene.setType("pano");
+//                    scene.setName(id);
+//                    //id生成规则是 s_ 拼接,随机8位字符串,字母加数字组合,有大小写
+//                    scene.setSceneCode(scenePanoEntity.getSceneCode());
+//                    scenes.add(scene);
+//                    if (i==0){
+//                        workEntity.setIcon(scenePanoEntity.getIcon());
+//                        workService.updateById(workEntity);
+//                    }
+//
+//                }
+//
+//                log.info("场景切图完成组装json");
+//                //修改为创建数据库
+//                String shareUrl = configConstant.domain4dKK + "/panorama/showMobile.html?id=" + workEntity.getId();
+//                String qrCode = qrCodeUtils.generateLogoQrCode(shareUrl, configConstant.serverBasePath, configConstant.ossBasePath, ossUtil.calculateUrl(""), workEntity.getId());
+//                workEntity.setQrCode(qrCode);
+//                workEntity.setShare(shareUrl);
+//
+//                //创建tour.xml
+//                this.saveTour(workEntity.getId());
+//
+//                WorkAddDto workAddDto = new WorkAddDto();
+//                workAddDto.setSceneDTOList(scenes);
+//
+//                this.initData(workAddDto, workEntity);
+//
+//                workEntity.setCalcStatus(1);
+//                workService.updateById(workEntity);
+//                sendEndMq(param);
+//                updateOssStatusJson(param.getSceneCode(),1);
+//                channel.basicAck(deliveryTag, false);
+//            }
+//            log.info("场景计算结束,队列名:{},id:{}", queueNameService.getQueueName(), messageId);
+//
+//
+//        }catch (Exception e){
+//            if (StrUtil.isNotEmpty(sceneCode)){
+//                updateOssStatusJson(sceneCode,0);
+//            }
+//            channel.basicAck(deliveryTag, false);
+//            log.error("场景sceneQueue报错{}",e.getMessage());
+//            e.printStackTrace();
+//        }
+//    }
+//
+//
+//
+//    private void initData(WorkAddDto workAddDto, WorkEntity entity){
+//        workNavigationSettingService.removeByWorkId(entity.getId());
+//        //添加默认分组
+//        WorkNavigationDTO defaultGroup = WorkNavigationDTO.builder().parentId(0L).name("一级分组").sort(0).build();
+//        defaultGroup.setWorkId(entity.getId());
+//        WorkNavigationVo workNavigationVo = workNavigationSettingService.addGroup(defaultGroup);
+//        List<WorkNavigationEntity> workNavigationEntities = BeanUtil.copyToList(workAddDto.getSceneDTOList(), WorkNavigationEntity.class);
+//        AtomicInteger sort = new AtomicInteger(0);
+//        workNavigationEntities.stream().forEach(v->{
+//            v.setParentId(workNavigationVo.getId());
+//            v.setWorkId(entity.getId());
+//            v.setSort(sort.getAndAdd(1));
+//        });
+//        workNavigationService.saveBatch(workNavigationEntities);
+//
+//        //初始化遮罩数据
+//        this.initMaskData(workNavigationEntities);
+//
+//        //初始化自定义按钮
+//        this.initCustomButton(entity.getId());
+//
+//        //初始化开场动画设置
+//        this.initOpenAnimation(entity.getId());
+//
+//        //初始化开场封面
+//        this.initWorkCoverType(entity.getId());
+//
+//        //初始化自定义logo
+//        this.initWorkLogo(entity.getId());
+//
+//        //初始化开场提示
+//        this.initWorkOpeningTip(entity.getId());
+//
+//    }
+//    public void initWorkOpeningTip(String workId){
+//        WorkOpeningTipEntity entity = new WorkOpeningTipEntity();
+//        entity.setWorkId(workId);
+//        entity.setIsRemind(1);
+//        entity.setRemindTime(1);
+//        workOpeningTipService.save(entity);
+//    }
+//    public void initWorkLogo(String workId){
+//        WorkLogoEntity entity = new WorkLogoEntity();
+//        entity.setWorkId(workId);
+//        entity.setIsLogo(1);
+//        workLogoService.save(entity);
+//    }
+//
+//    public void initOpenAnimation(String workId){
+//        WorkOpeningAnimationEntity entity = new WorkOpeningAnimationEntity();
+//        entity.setIsShowOpeningAnimation(true);
+//        entity.setOpeningAnimationType(1);
+//        entity.setWorkId(workId);
+//        workOpeningAnimationService.save(entity);
+//    }
+//    public void initWorkCoverType(String workId){
+//        WorkCoverTypeEntity entity = new WorkCoverTypeEntity();
+//        entity.setWorkId(workId);
+//        entity.setCoverSelect("img");
+//        entity.setCoverPcLoc("center");
+//        entity.setCoverMoLoc("center");
+//        entity.setCoverImgBac("colorFill");
+//        entity.setImgColorSelec("#000000");
+//        entity.setCoverImageInWay(1);
+//        workCoverTypeService.save(entity);
+//    }
+//
+//
+//    private void initCustomButton(String workId){
+//        WorkCustomButtonEntity phoneButton = new WorkCustomButtonEntity();
+//        phoneButton.setWorkId(workId);
+//        phoneButton.setIsShow(0);
+//        phoneButton.setName("电话");
+//        phoneButton.setType("phone");
+//        phoneButton.setOpenMethod("_self");
+//        phoneButton.setCreateTime(new Date());
+//
+//        WorkCustomButtonEntity linkButton = BeanUtil.toBean(phoneButton, WorkCustomButtonEntity.class);
+//        linkButton.setName("链接");
+//
+//        workCustomButtonService.saveBatch(Arrays.asList(phoneButton, linkButton));
+//
+//    }
+//
+//    private void initMaskData(List<WorkNavigationEntity> workNavigations){
+//        List<WorkCustomMaskEntity> list = new ArrayList<>();
+//        workNavigations.stream().forEach(v->{
+//            WorkCustomMaskEntity sky = new WorkCustomMaskEntity();
+//            sky.setWorkId(v.getWorkId());
+//            sky.setNavigationId(v.getId());
+//            sky.setIsShow(true);
+//            sky.setType("sky");
+//            sky.setAntidistorted(true);
+//            sky.setScale(1D);
+//            list.add(sky);
+//
+//            WorkCustomMaskEntity earth = BeanUtil.toBean(sky, WorkCustomMaskEntity.class);
+//            earth.setType("earth");
+//            earth.setIsShow(false);
+//            list.add(earth);
+//        });
+//        if(CollUtil.isNotEmpty(list)){
+//            workCustomMaskService.saveBatch(list);
+//        }
+//    }
+//
+//    private void updateOssStatusJson(String sceneCode, int status) throws Exception {
+//        //修改OSS,status状态 scene_view_data/场景码/data/status.json
+//        String statusJson = "scene_view_data/"+sceneCode+"/data/status.json";
+//        Boolean exist=ossUtil.doesObjectExist("4dkankan",statusJson);
+//        if (exist){
+//            String fileContent = ossUtil.getFileContent("4dkankan", statusJson);
+//                log.info("statusJson存在: {}",statusJson);
+//                JSONObject statusJsonObj = JSONObject.parseObject(fileContent);
+//                statusJsonObj.put("status",status);
+//                ossUtil.uploadFileBytes("4dkankan",statusJson,statusJsonObj.toJSONString().getBytes(StandardCharsets.UTF_8));
+//
+//        }
+//    }
+//
+//    private void sendStartMq(SceneQueueDTO param) {
+//            RelicsSceneInitQueueDTO relicsSceneInitQueueDTO = new RelicsSceneInitQueueDTO();
+//            relicsSceneInitQueueDTO.setSceneCode(param.getSceneCode());
+//            relicsSceneInitQueueDTO.setLocation(param.getLocation());
+//            relicsSceneInitQueueDTO.setCreateTime(param.getCreateTime());
+//            relicsSceneInitQueueDTO.setPhoneNum(param.getPhoneNum());
+//            relicsSceneInitQueueDTO.setUserId(param.getUserId());
+//            relicsSceneInitQueueDTO.setSnCode(param.getSnCode());
+//            relicsSceneInitQueueDTO.setStatus(param.getStatus());
+//            relicsSceneInitQueueDTO.setSceneName(param.getSceneName());
+//            relicsSceneInitQueueDTO.setShootCount(param.getShootCount());
+//            relicsSceneInitQueueDTO.setSceneSource(param.getSceneSource());
+//            relicsSceneInitQueueDTO.setPayStatus(param.getPayStatus());
+//            rabbitMqProducerUtil.sendByWorkQueue(relicsInitQueue, relicsSceneInitQueueDTO);
+//    }
+//    private void sendEndMq(SceneQueueDTO param) {
+//            RelicsSceneInitQueueDTO relicsSceneInitQueueDTO = new RelicsSceneInitQueueDTO();
+//            relicsSceneInitQueueDTO.setSceneCode(param.getSceneCode());
+//            relicsSceneInitQueueDTO.setLocation(param.getLocation());
+//            relicsSceneInitQueueDTO.setAlgorithmTime(param.getAlgorithmTime());
+//            relicsSceneInitQueueDTO.setCreateTime(param.getCreateTime());
+//            relicsSceneInitQueueDTO.setPhoneNum(param.getPhoneNum());
+//            relicsSceneInitQueueDTO.setUserId(param.getUserId());
+//            relicsSceneInitQueueDTO.setSnCode(param.getSnCode());
+//            relicsSceneInitQueueDTO.setStatus(param.getStatus());
+//            relicsSceneInitQueueDTO.setSceneName(param.getSceneName());
+//            relicsSceneInitQueueDTO.setShootCount(param.getShootCount());
+//            relicsSceneInitQueueDTO.setSceneSource(param.getSceneSource());
+//            relicsSceneInitQueueDTO.setPayStatus(param.getPayStatus());
+//        rabbitMqProducerUtil.sendByWorkQueue(relicsInitQueue, relicsSceneInitQueueDTO);
+//    }
+//
+//    private static final String CHARACTERS = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
+//
+//    public static String generateRandomId() {
+//        Random random = new Random();
+//        StringBuilder sb = new StringBuilder();
+//        for (int i = 0; i < 8; i++) {
+//            int index = random.nextInt(CHARACTERS.length());
+//            sb.append(CHARACTERS.charAt(index));
+//        }
+//        return sb.toString();
+//    }
+//
+//    public static String generateCustomId() {
+//        return "s_" + generateRandomId();
+//    }
+//    private ScenePanoEntity doSlice(String traceId, String item, String num, String workId, String imgName, String uuid, String id){
+//        ScenePanoEntity entity=scenePanoService.findByWorkIdAndName(workId,imgName);
+//        String sceneCode ="";
+//        String newName = "";
+//        String filePath = "";
+//        if (ObjectUtil.isEmpty(entity)) {
+//            //未生成
+//            sceneCode = RandomUtils.getSceneCode("fd720_");
+//            newName = sceneCode + ".jpg";
+//            filePath = configConstant.serverBasePath + sceneCode+ "/" + newName;
+//            ossUtil.downloadFile("4dkankan",item,filePath );
+//
+//            entity = new ScenePanoEntity();
+//            entity.setFilePath(filePath);
+//            entity.setFileName(FileUtil.getName(filePath));
+//            entity.setSceneCode(sceneCode);
+//            entity.setNum(num);
+//            entity.setOssPath(item);
+//            entity.setName(imgName);
+//            entity.setWorkId(workId);
+//            entity.setVisid(id);
+//            entity.setUuid(uuid);
+//            long size = FileUtil.size(new File(filePath));
+//            size = size / 1024;
+//            log.info("fileSize: " + size);
+//            entity.setFileSize(size + "");
+//
+//            scenePanoService.save(entity);
+//        }else {
+//            entity.setStatus(0);
+//
+//            filePath = entity.getFilePath();
+//            sceneCode = entity.getSceneCode();
+//            boolean exist = FileUtil.exist(filePath);
+//            if (exist){
+//                FileUtil.del(filePath);
+//            }
+//            if (filePath.endsWith(".jpg")){
+//                String parent = FileUtil.getParent(filePath, 1);
+//                FileUtil.del(parent);
+//            }
+//
+//
+//            log.info("生成过,重新下载");
+//            ossUtil.downloadFile("4dkankan",item,filePath );
+//            log.info("下载完成重新切图");
+//            long size = FileUtil.size(new File(filePath));
+//            size = size / 1024;
+//            log.info("fileSize: " + size);
+//            entity.setFileSize(size + "");
+//            scenePanoService.updateById(entity);
+//
+//        }
+//
+//
+//        log.info("切图流程开始 : " + filePath);
+//        long start = System.currentTimeMillis();
+//
+//        String cmd = CmdConstant.PANO_KRPANO + filePath;
+//        // 超时处理机制
+//        final ExecutorService exec = Executors.newFixedThreadPool(1);
+//        Callable<String> call = new Callable<String>() {
+//            @Override
+//            public String call() throws Exception {
+//                MDC.put("TRACE_ID", traceId);
+//                CmdUtils.callLine(cmd, 200);
+//                long end = System.currentTimeMillis();
+//                log.info("切图完成耗时: {} s" ,(end-start)/1000);
+//                return "执行完成";
+//            }
+//        };
+//        // 超时回调
+//        Future<String> future = exec.submit(call);
+//        try {
+//            String obj = future.get(20, TimeUnit.MINUTES); //任务处理超时时间设为 3分钟
+//            entity.setStatus(3);
+//            String tourXmlScene = this.getTourXmlScene(sceneCode);
+//            entity.setTour(tourXmlScene);
+//            // 上传切图
+//            this.uploadOss(sceneCode);
+//            String ossUrl = ossUtil.calculateUrl("") + configConstant.ossBasePath + sceneCode+"/vtour/panos/"+sceneCode+".tiles/thumb.jpg";
+//            log.info("切图预览图ossUrl: {}",ossUrl);
+//            entity.setIcon(ossUrl);
+//            log.info("任务成功返回: " + obj);
+//
+//        } catch (InterruptedException e) {
+//            e.printStackTrace();
+//            entity.setStatus(2);
+//            StringWriter trace=new StringWriter();
+//            log.error(trace.toString());
+//            log.error("异常了 InterruptedException");
+//        } catch (ExecutionException | BaseRuntimeException e) {
+//            e.printStackTrace();
+//            StringWriter trace=new StringWriter();
+//            e.printStackTrace(new PrintWriter(trace));
+//            log.error("超时了 1");
+//            // 异常日志要打印,不然不会出现在日志文件中,只会出现在控制台
+//            log.error(trace.toString());
+//            entity.setStatus(2);
+//            future.cancel(true);
+//        } catch (TimeoutException e) {
+//            e.printStackTrace();
+//            StringWriter trace=new StringWriter();
+//            e.printStackTrace(new PrintWriter(trace));
+//            log.error("超时了 2");
+//            log.error(trace.toString());
+//            entity.setStatus(2);
+//            future.cancel(true);
+//        } finally {
+//            scenePanoService.updateById(entity);
+//            log.info("切图流程, 更新数据库完成 : ");
+//        }
+//        log.info("切图流程结束 : ");
+//        return entity;
+//    }
+//
+//    /**
+//     * 更新 tour.xml
+//     * @param id
+//     */
+//    private void saveTour(String id) {
+//        List<ScenePanoEntity> list = scenePanoService.findByWorkId(id);
+//        // 读取tour.xml模板
+//        String baseTour = getBaseTour();
+//        StringBuilder builder = new StringBuilder();
+//        builder.append(baseTour).append("\r\n");
+//        for (ScenePanoEntity entity : list) {
+//            String tour = entity.getTour();
+//            builder.append(tour).append("\r\n");
+//        }
+//
+//        // 添加结束标签
+//        builder.append("</krpano>");
+//
+//        String tourPath = configConstant.serverBasePath + id + "/tour.xml";
+//        FileUtil.writeUtf8String(builder.toString(), tourPath);
+//        log.info("作品tour.xml写入完成");
+//
+//        String ossKeyPath = configConstant.ossBasePath + id + "/tour.xml";
+//        ossUtil.uploadFile( ossKeyPath,tourPath);
+//        log.info("tour.xml上传完成 : {}", ossKeyPath);
+//    }
+//
+//    private String getBaseTour(){
+//        String baseTourPath = configConstant.serverBasePath + "baseData/tour.xml";
+//        String s = FileUtil.readString(baseTourPath, "utf-8");
+//        // 结束标签置空, 方便操作
+//        s = s.replace("</krpano>", "");
+//        return s;
+//    }
+//
+//    // 获取切图后的tour.xml
+//    private String getTourXmlScene(String code) {
+//        log.info("处理tour.xml");
+//        String tourPath = configConstant.serverBasePath + code + "/vtour/tour.xml";
+//        log.info("tourPath: {}", tourPath);
+//        BaseRuntimeException.isTrue(!FileUtil.isFile(tourPath), null, code + "_tour.xml文件不存在");
+//
+//        String tour = FileUtil.readUtf8String(tourPath);
+//        tour = this.extractSceneTag(tour);
+//        String trim = StrUtil.trim(tour);
+//        // log.info("trim: {}", trim);
+//        BaseRuntimeException.isTrue(StrUtil.isAllBlank(trim), null, code + "_tour.xml文件不存在");
+//
+//        // 2022-09-15 加入相对路径
+//        String basePath = "%CURRENTXML%../" + code + "/vtour/panos/";
+//        trim = trim.replaceAll("panos/", basePath);
+//
+//        return trim;
+//    }
+//    public static String extractSceneTag(String xmlString) {
+//        Pattern pattern = Pattern.compile("<scene.*?</scene>", Pattern.DOTALL);
+//        Matcher matcher = pattern.matcher(xmlString);
+//
+//        if (matcher.find()) {
+//            return matcher.group();
+//        }
+//
+//        return "";
+//    }
+//    private void uploadOss(String sceneCode) {
+//        long start = System.currentTimeMillis();
+//        String filePath = "/mnt/720yun_fd_manage_data/" + sceneCode;
+//        String ossKey = "720yun_fd_manage/" + sceneCode;
+//        fileAndOssUtil.uploadBySh(filePath, ossKey);
+//        long end = System.currentTimeMillis();
+//        log.info("切图上传完成, 耗时:{} s" , (end-start)/1000 );
+//    }
+//
+//
+//
+//
+//
+//    public static void main(String[] args) {
+//        List<String> list=new ArrayList<>();
+//        list.add("scene_view_data/KJ-t-QPqp92mGf1c/images/pan/high/0.jpg");
+//        list.add("scene_view_data/KJ-t-QPqp92mGf1c/images/pan/high/1.jpg");
+//        list.add("scene_view_data/KJ-t-QPqp92mGf1c/images/pan/high/3.jpg");
+//        list.add("scene_view_data/KJ-t-QPqp92mGf1c/images/pan/high/4.jpg");
+//        //循环只打印文件是偶数的图片
+//
+//    }
+//}

+ 92 - 0
720yun_fd_consumer/src/main/java/com/gis/listener/SceneMigrateListener.java

@@ -0,0 +1,92 @@
+//package com.gis.listener;
+//
+//import cn.hutool.core.util.ObjectUtil;
+//import cn.hutool.core.util.StrUtil;
+//import com.alibaba.fastjson.JSON;
+//import com.alibaba.fastjson.JSONObject;
+//import com.gis.constant.ConfigConstant;
+//import com.gis.domain.dto.OpenSceneMigrateDto;
+//import com.gis.entity.WorkEntity;
+//import com.gis.mq.RabbitMqProducerUtil;
+//import com.gis.oss.util.FileAndOssUtil;
+//import com.gis.service.ScenePanoService;
+//import com.gis.service.WorkService;
+//import com.gis.util.QrCodeUtils;
+//import com.rabbitmq.client.Channel;
+//import lombok.extern.slf4j.Slf4j;
+//import org.slf4j.MDC;
+//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.context.annotation.Conditional;
+//import org.springframework.stereotype.Component;
+//import org.springframework.util.ObjectUtils;
+//
+//import java.io.IOException;
+//import java.nio.charset.StandardCharsets;
+//
+///**
+// * 消息监听器
+// *
+// * @author Xiewj
+// * @version 1.0
+// * @since 2023/08/07
+// */
+//@Component
+//@Slf4j
+//public class SceneMigrateListener {
+//
+//    @Autowired
+//    ConfigConstant configConstant;
+//    @Autowired
+//    FileAndOssUtil fileAndOssUtil;
+//    @Autowired
+//    WorkService workService;
+//    @Autowired
+//    QrCodeUtils qrCodeUtils;
+//    @Autowired
+//    ScenePanoService scenePanoService;
+//    @Autowired
+//    RabbitMqProducerUtil rabbitMqProducerUtil;
+//    /**
+//     * 全景场景初始化方法
+//     *
+//     * @param channel
+//     * @param message
+//     * @throws Exception the io exception  这里异常需要处理
+//     */
+//    @RabbitListener(
+//            queuesToDeclare = @Queue("${queue.pano-migrate-scene-queue}"),concurrency = "1"
+//    )
+//    @Conditional(NonDynamicListenerCondition.class)
+//    public void migrateSceneQueue(Channel channel, Message message) throws IOException {
+//            if (ObjectUtils.isEmpty(message.getBody())) {
+//                log.error("消息内容为空,退出构建,当前服务器id:{}" );
+//                return;
+//            }
+//        String traceId = System.currentTimeMillis()+"";
+//        MDC.put("TRACE_ID", traceId);
+//        long deliveryTag = message.getMessageProperties().getDeliveryTag();
+//        try {
+//            String msg = new String(message.getBody(), StandardCharsets.UTF_8);
+//            String messageId = message.getMessageProperties().getMessageId();
+//            log.info("场景migrateSceneQueue开始,id:{},deliveryTag:{},消息体:{}", messageId,deliveryTag,msg);
+//            OpenSceneMigrateDto param = JSONObject.parseObject(JSON.parse(msg).toString(), OpenSceneMigrateDto.class);
+//            if (StrUtil.isNotEmpty(param.getSceneCode())&&StrUtil.isEmpty(param.getSnCode())) {
+//                WorkEntity workEntity=workService.findByNum(param.getSceneCode());
+//                if (ObjectUtil.isNotNull(workEntity)) {
+//                    workEntity.setSnCode(param.getToSnCode());
+//                    workEntity.setUserId(param.getPhone());
+//                    workService.updateById(workEntity);
+//                }
+//            }
+//        }catch (Exception e){
+//            channel.basicAck(deliveryTag, false);
+//            log.error("场景migrateSceneQueue报错{}",e.getMessage());
+//            e.printStackTrace();
+//        }
+//        channel.basicAck(deliveryTag, false);
+//    }
+//
+//}

+ 80 - 0
720yun_fd_consumer/src/main/java/com/gis/listener/ScenePayStatusListener.java

@@ -0,0 +1,80 @@
+//package com.gis.listener;
+//
+//import cn.hutool.core.util.ArrayUtil;
+//import cn.hutool.core.util.ObjectUtil;
+//import com.alibaba.fastjson.JSONObject;
+//import com.gis.domain.dto.SceneQueueDTO;
+//import com.gis.entity.WorkEntity;
+//import com.gis.service.WorkService;
+//import com.rabbitmq.client.Channel;
+//import lombok.extern.slf4j.Slf4j;
+//import org.slf4j.MDC;
+//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.context.annotation.Conditional;
+//import org.springframework.stereotype.Component;
+//import org.springframework.util.ObjectUtils;
+//
+//import java.io.IOException;
+//import java.nio.charset.StandardCharsets;
+//
+///**
+// * 消息监听器
+// *
+// * @author Xiewj
+// * @version 1.0
+// * @since 2023/08/07
+// */
+//@Component
+//@Slf4j
+//public class ScenePayStatusListener {
+//
+//    @Autowired
+//    WorkService workService;
+//    /**
+//     * 全景场景初始化方法
+//     *
+//     * @param channel
+//     * @param message
+//     * @throws Exception the io exception  这里异常需要处理
+//     */
+//    @RabbitListener(
+//            queuesToDeclare = @Queue("${queue.pano-paystatus-scene-queue}"),concurrency = "1"
+//    )
+//    @Conditional(NonDynamicListenerCondition.class)
+//    public void scenePayStatusQueue(Channel channel, Message message) throws IOException {
+//            if (ObjectUtils.isEmpty(message.getBody())) {
+//                log.error("消息内容为空,退出构建,当前服务器id:{}" );
+//                return;
+//            }
+//        String traceId = System.currentTimeMillis()+"";
+//        MDC.put("TRACE_ID", traceId);
+//        long deliveryTag = message.getMessageProperties().getDeliveryTag();
+//        try {
+//            String msg = new String(message.getBody(), StandardCharsets.UTF_8);
+//            String messageId = message.getMessageProperties().getMessageId();
+//            log.info("场景scenePayStatusQueue开始,id:{},deliveryTag:{},消息体:{}", messageId,deliveryTag,msg);
+//            SceneQueueDTO param = JSONObject.parseObject(msg, SceneQueueDTO.class);
+//            if (ObjectUtil.isEmpty(param.getSceneCodes())&& ArrayUtil.isNotEmpty(param.getSceneCodes())) {
+//                log.error("参数列表错误(缺少),格式不匹配,{}",param);
+//                channel.basicAck(deliveryTag, false);
+//            }
+//            for (String sceneCode : param.getSceneCodes()) {
+//                WorkEntity workEntity=workService.findByNum(sceneCode);
+//                if (ObjectUtil.isNotNull(workEntity)){
+//                    //修改状态
+//                    workEntity.setPayStatus(param.getPayStatus());
+//                    workService.updateById(workEntity);
+//                }
+//            }
+//            channel.basicAck(deliveryTag, false);
+//        }catch (Exception e){
+//            channel.basicAck(deliveryTag, false);
+//            log.error("场景sceneQueue报错{}",e.getMessage());
+//            e.printStackTrace();
+//
+//        }
+//    }
+//}

+ 49 - 0
720yun_fd_consumer/src/main/java/com/gis/listener/container/DoSliceQueueListener.java

@@ -0,0 +1,49 @@
+package com.gis.listener.container;
+import com.alibaba.fastjson.JSONObject;
+import com.gis.domain.dto.DoSliceDTO;
+import com.gis.service.FodderService;
+import lombok.extern.slf4j.Slf4j;
+import org.slf4j.MDC;
+import org.springframework.amqp.rabbit.listener.api.ChannelAwareMessageListener;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+import com.rabbitmq.client.Channel;
+import org.springframework.amqp.core.Message;
+import org.springframework.util.ObjectUtils;
+
+import java.nio.charset.StandardCharsets;
+
+/**
+ * @author Xiewj
+ * @date 2025/3/19
+ */
+@Component
+@Slf4j
+public class DoSliceQueueListener implements ChannelAwareMessageListener {
+    @Autowired
+    FodderService fodderService;
+
+    @Override
+    public void onMessage(Message message, Channel channel) throws Exception {
+
+        if (ObjectUtils.isEmpty(message.getBody())) {
+            log.error("消息内容为空,退出构建,当前服务器id:{}" );
+            return;
+        }
+        String traceId = System.currentTimeMillis()+"";
+        MDC.put("TRACE_ID", traceId);
+        long deliveryTag = message.getMessageProperties().getDeliveryTag();
+        try {
+            String msg = new String(message.getBody(), StandardCharsets.UTF_8);
+            String messageId = message.getMessageProperties().getMessageId();
+            log.info("场景doSliceQueue开始,id:{},deliveryTag:{},消息体:{}", messageId,deliveryTag,msg);
+            DoSliceDTO dto = JSONObject.parseObject(msg, DoSliceDTO.class);
+            fodderService.doSlice(dto.getId(), traceId);
+        }catch (Exception e){
+            e.printStackTrace();
+            log.error("场景doSliceQueue报错{}",e.getMessage());
+        }finally {
+            channel.basicAck(deliveryTag, false);
+        }
+    }
+}

+ 63 - 0
720yun_fd_consumer/src/main/java/com/gis/listener/container/PanoMigrateSceneQueueListener.java

@@ -0,0 +1,63 @@
+package com.gis.listener.container;
+
+import cn.hutool.core.util.ObjectUtil;
+import cn.hutool.core.util.StrUtil;
+import com.alibaba.fastjson.JSON;
+import com.alibaba.fastjson.JSONObject;
+import com.gis.domain.entity.WorkEntity;
+import com.gis.domain.dto.OpenSceneMigrateDto;
+import com.gis.service.FodderService;
+import com.gis.service.WorkService;
+import com.rabbitmq.client.Channel;
+import lombok.extern.slf4j.Slf4j;
+import org.slf4j.MDC;
+import org.springframework.amqp.core.Message;
+import org.springframework.amqp.rabbit.listener.api.ChannelAwareMessageListener;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+import org.springframework.util.ObjectUtils;
+
+import java.nio.charset.StandardCharsets;
+
+/**
+ * @author Xiewj
+ * @date 2025/3/19
+ */
+@Component
+@Slf4j
+public class PanoMigrateSceneQueueListener implements ChannelAwareMessageListener {
+    @Autowired
+    FodderService fodderService;
+    @Autowired
+    WorkService workService;
+    @Override
+    public void onMessage(Message message, Channel channel) throws Exception {
+
+        if (ObjectUtils.isEmpty(message.getBody())) {
+            log.error("消息内容为空,退出构建,当前服务器id:{}" );
+            return;
+        }
+        String traceId = System.currentTimeMillis()+"";
+        MDC.put("TRACE_ID", traceId);
+        long deliveryTag = message.getMessageProperties().getDeliveryTag();
+        try {
+            String msg = new String(message.getBody(), StandardCharsets.UTF_8);
+            String messageId = message.getMessageProperties().getMessageId();
+            log.info("场景migrateSceneQueue开始,id:{},deliveryTag:{},消息体:{}", messageId,deliveryTag,msg);
+            OpenSceneMigrateDto param = JSONObject.parseObject(JSON.parse(msg).toString(), OpenSceneMigrateDto.class);
+            if (StrUtil.isNotEmpty(param.getSceneCode())&&StrUtil.isEmpty(param.getSnCode())) {
+                WorkEntity workEntity=workService.findByNum(param.getSceneCode());
+                if (ObjectUtil.isNotNull(workEntity)) {
+                    workEntity.setSnCode(param.getToSnCode());
+                    workEntity.setUserId(param.getPhone());
+                    workService.updateById(workEntity);
+                }
+            }
+        }catch (Exception e){
+            log.error("场景migrateSceneQueue报错{}",e.getMessage());
+            e.printStackTrace();
+        }finally {
+            channel.basicAck(deliveryTag, false);
+        }
+    }
+}

+ 67 - 0
720yun_fd_consumer/src/main/java/com/gis/listener/container/PanoPayStatusSceneQueueListener.java

@@ -0,0 +1,67 @@
+package com.gis.listener.container;
+
+import cn.hutool.core.util.ArrayUtil;
+import cn.hutool.core.util.ObjectUtil;
+import com.alibaba.fastjson.JSONObject;
+import com.gis.domain.entity.WorkEntity;
+import com.gis.domain.dto.SceneQueueDTO;
+import com.gis.service.FodderService;
+import com.gis.service.WorkService;
+import com.rabbitmq.client.Channel;
+import lombok.extern.slf4j.Slf4j;
+import org.slf4j.MDC;
+import org.springframework.amqp.core.Message;
+import org.springframework.amqp.rabbit.listener.api.ChannelAwareMessageListener;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+import org.springframework.util.ObjectUtils;
+
+import java.nio.charset.StandardCharsets;
+
+/**
+ * @author Xiewj
+ * @date 2025/3/19
+ */
+@Component
+@Slf4j
+public class PanoPayStatusSceneQueueListener implements ChannelAwareMessageListener {
+    @Autowired
+    FodderService fodderService;
+    @Autowired
+    WorkService workService;
+    @Override
+    public void onMessage(Message message, Channel channel) throws Exception {
+        if (ObjectUtils.isEmpty(message.getBody())) {
+            log.error("消息内容为空,退出构建,当前服务器id:{}" );
+            return;
+        }
+        String traceId = System.currentTimeMillis()+"";
+        MDC.put("TRACE_ID", traceId);
+        long deliveryTag = message.getMessageProperties().getDeliveryTag();
+        try {
+            String msg = new String(message.getBody(), StandardCharsets.UTF_8);
+            String messageId = message.getMessageProperties().getMessageId();
+            log.info("场景scenePayStatusQueue开始,id:{},deliveryTag:{},消息体:{}", messageId,deliveryTag,msg);
+            SceneQueueDTO param = JSONObject.parseObject(msg, SceneQueueDTO.class);
+            if (ObjectUtil.isEmpty(param.getSceneCodes())&& ArrayUtil.isNotEmpty(param.getSceneCodes())) {
+                log.error("参数列表错误(缺少),格式不匹配,{}",param);
+                channel.basicAck(deliveryTag, false);
+                return;
+            }
+            for (String sceneCode : param.getSceneCodes()) {
+                WorkEntity workEntity=workService.findByNum(sceneCode);
+                if (ObjectUtil.isNotNull(workEntity)){
+                    //修改状态
+                    workEntity.setPayStatus(param.getPayStatus());
+                    workService.updateById(workEntity);
+                }
+            }
+        }catch (Exception e){
+            log.error("场景sceneQueue报错{}",e.getMessage());
+            e.printStackTrace();
+        }finally {
+            channel.basicAck(deliveryTag, false);
+
+        }
+    }
+}

+ 141 - 0
720yun_fd_consumer/src/main/java/com/gis/listener/container/RabbitMQConfig.java

@@ -0,0 +1,141 @@
+package com.gis.listener.container;
+
+import com.gis.receiver.QueueNameService;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.amqp.core.AcknowledgeMode;
+import org.springframework.amqp.core.Queue;
+import org.springframework.amqp.rabbit.connection.ConnectionFactory;
+import org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+
+/**
+ * @author Xiewj
+ * @date 2025/3/19
+ */
+@Configuration
+@Slf4j
+public class RabbitMQConfig {
+
+    @Value("${mq.listener.dynamic}")
+    private boolean isDynamic;
+
+    @Value("${queue.do-slice-queue}")
+    String doSliceQueue;
+
+    @Value("${queue.pano-migrate-scene-queue}")
+    String panoMigrateSceneQueue;
+
+    @Value("${queue.pano-paystatus-scene-queue}")
+    String panoPayStatusSceneQueue;
+
+    @Value("${queue.scene-queue}")
+    String sceneQueue;
+
+    @Autowired
+    QueueNameService queueNameService;
+    @Autowired
+    SceneWorkQueueListener sceneWorkQueueListener;
+    @Autowired
+    PanoMigrateSceneQueueListener panoMigrateSceneQueueListener;
+    @Autowired
+    DoSliceQueueListener doSliceQueueListener;
+    @Autowired
+    PanoPayStatusSceneQueueListener panoPayStatusSceneQueueListener;
+    @Autowired
+    SceneQueueListener sceneQueueListener;
+
+
+    @Bean
+    public Queue doSliceQueue() {
+        return new Queue(doSliceQueue, true, false, false);
+    }
+
+    @Bean
+    public Queue panoMigrateSceneQueue() {
+        return new Queue(panoMigrateSceneQueue, true, false, false);
+    }
+
+    @Bean
+    public Queue panoPayStatusSceneQueue() {
+        return new Queue(panoPayStatusSceneQueue, true, false, false);
+    }
+
+    @Bean
+    public Queue sceneQueue() {
+        return new Queue(sceneQueue, true, false, false);
+    }
+
+    @Bean
+    public Queue sceneWorkQueue() {
+        return new Queue(queueNameService.getQueueName(), true, false, false);
+    }
+
+    @Bean
+    public SimpleMessageListenerContainer doSliceQueueContainer(ConnectionFactory connectionFactory) {
+        SimpleMessageListenerContainer container = new SimpleMessageListenerContainer(connectionFactory);
+        log.info("doSliceQueue 启动,监听队列-{},动态伸缩启动-{}", doSliceQueue, !isDynamic);
+        container.setQueueNames(doSliceQueue);
+        container.setMessageListener(doSliceQueueListener);
+        container.setAutoStartup(!isDynamic); // 根据配置决定是否自动启动
+        container.setPrefetchCount(2);
+        container.setAcknowledgeMode(AcknowledgeMode.MANUAL);
+        container.setErrorHandler(t -> log.error("doSliceQueue 监听器发生异常", t));
+        return container;
+    }
+
+    @Bean
+    public SimpleMessageListenerContainer panoMigrateSceneQueueContainer(ConnectionFactory connectionFactory) {
+        SimpleMessageListenerContainer container = new SimpleMessageListenerContainer(connectionFactory);
+        log.info("panoMigrateSceneQueue 启动,监听队列-{},动态伸缩启动-{}", panoMigrateSceneQueue, !isDynamic);
+        container.setQueueNames(panoMigrateSceneQueue);
+        container.setMessageListener(panoMigrateSceneQueueListener);
+        container.setAutoStartup(!isDynamic); // 根据配置决定是否自动启动
+        container.setPrefetchCount(1);
+        container.setAcknowledgeMode(AcknowledgeMode.MANUAL);
+        container.setErrorHandler(t -> log.error("panoMigrateSceneQueue 监听器发生异常", t));
+        return container;
+    }
+
+    @Bean
+    public SimpleMessageListenerContainer panoPayStatusSceneQueueContainer(ConnectionFactory connectionFactory) {
+        SimpleMessageListenerContainer container = new SimpleMessageListenerContainer(connectionFactory);
+        log.info("panoPayStatusSceneQueue 启动,监听队列-{},动态伸缩启动-{}", panoPayStatusSceneQueue, !isDynamic);
+        container.setQueueNames(panoPayStatusSceneQueue);
+        container.setMessageListener(panoPayStatusSceneQueueListener);
+        container.setAutoStartup(!isDynamic); // 根据配置决定是否自动启动
+        container.setPrefetchCount(1);
+        container.setAcknowledgeMode(AcknowledgeMode.MANUAL);
+        container.setErrorHandler(t -> log.error("panoPayStatusSceneQueue 监听器发生异常", t));
+        return container;
+    }
+
+    @Bean
+    public SimpleMessageListenerContainer sceneQueueContainer(ConnectionFactory connectionFactory) {
+        SimpleMessageListenerContainer container = new SimpleMessageListenerContainer(connectionFactory);
+        log.info("sceneQueue 启动,监听队列-{},动态伸缩启动-{}", sceneQueue, !isDynamic);
+        container.setQueueNames(sceneQueue);
+        container.setMessageListener(sceneQueueListener);
+        container.setAutoStartup(!isDynamic); // 根据配置决定是否自动启动
+        container.setPrefetchCount(1);
+        container.setAcknowledgeMode(AcknowledgeMode.MANUAL);
+        container.setErrorHandler(t -> log.error("sceneQueue 监听器发生异常", t));
+        return container;
+    }
+
+    @Bean
+    public SimpleMessageListenerContainer sceneWorkQueueContainer(ConnectionFactory connectionFactory) {
+        SimpleMessageListenerContainer container = new SimpleMessageListenerContainer(connectionFactory);
+        String queueName = queueNameService.getQueueName();
+        log.info("sceneWorkQueue 启动,监听队列-{},动态伸缩启动-{}", queueName, isDynamic);
+        container.setQueueNames(queueName);
+        container.setMessageListener(sceneWorkQueueListener);
+        container.setAutoStartup(true); // 根据配置决定是否自动启动
+        container.setPrefetchCount(2);
+        container.setAcknowledgeMode(AcknowledgeMode.MANUAL);
+        container.setErrorHandler(t -> log.error("sceneWorkQueue 监听器发生异常", t));
+        return container;
+    }
+}

+ 203 - 0
720yun_fd_consumer/src/main/java/com/gis/listener/container/SceneQueueListener.java

@@ -0,0 +1,203 @@
+package com.gis.listener.container;
+
+import cn.hutool.core.util.ObjectUtil;
+import cn.hutool.core.util.StrUtil;
+import com.alibaba.fastjson.JSONObject;
+import com.fdkankan.filestorage.FileStorageTemplate;
+import com.gis.common.constant.ConfigConstant;
+import com.gis.common.mq.RabbitMqProducerUtil;
+import com.gis.domain.dto.RelicsSceneInitQueueDTO;
+import com.gis.domain.entity.MqSendLog;
+import com.gis.domain.entity.WorkEntity;
+import com.gis.domain.dto.SceneQueueDTO;
+import com.gis.oss.util.QrCodeUtils;
+import com.gis.service.*;
+import com.rabbitmq.client.Channel;
+import lombok.extern.slf4j.Slf4j;
+import org.slf4j.MDC;
+import org.springframework.amqp.core.Message;
+import org.springframework.amqp.rabbit.listener.api.ChannelAwareMessageListener;
+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 javax.annotation.Resource;
+import java.nio.charset.StandardCharsets;
+import java.util.*;
+
+/**
+ * @author Xiewj
+ * @date 2025/3/19
+ */
+@Component
+@Slf4j
+public class SceneQueueListener implements ChannelAwareMessageListener {
+    @Autowired
+    FodderService fodderService;
+    @Autowired
+    WorkService workService;
+    @Autowired
+    ConfigConstant configConstant;
+    @Autowired
+    QrCodeUtils qrCodeUtils;
+    @Autowired
+    ScenePanoService scenePanoService;
+    @Autowired
+    RabbitMqProducerUtil rabbitMqProducerUtil;
+    @Value("${queue.relics-init-queue}")
+    String relicsInitQueue;
+
+    @Value("${queue.scene-queue-work}")
+    String sceneQueueWork;
+    @Resource
+    private FileStorageTemplate ossUtil;
+
+    @Value("${domain.4dkk}")
+    public  String domain4dKK;
+
+
+    @Autowired
+    WorkCoverTypeService workCoverTypeService;
+
+    @Autowired
+    WorkLogoService workLogoService;
+
+    @Autowired
+    WorkOpeningTipService workOpeningTipService;
+
+    @Autowired
+    WorkOpeningAnimationService workOpeningAnimationService;
+
+    @Autowired
+    IMqSendLogService mqSendLogService;
+
+
+    @Override
+    public void onMessage(Message message, Channel channel) throws Exception {
+        if (ObjectUtils.isEmpty(message.getBody())) {
+            log.error("消息内容为空,退出构建,当前服务器id:{}" );
+            return;
+        }
+        String traceId = System.currentTimeMillis()+"";
+        MDC.put("TRACE_ID", traceId);
+        String sceneCode="";
+        long deliveryTag = message.getMessageProperties().getDeliveryTag();
+        try {
+            String msg = new String(message.getBody(), StandardCharsets.UTF_8);
+            String messageId = message.getMessageProperties().getMessageId();
+            log.info("场景sceneQueue开始,id:{},deliveryTag:{},消息体:{}", messageId,deliveryTag,msg);
+            SceneQueueDTO param = JSONObject.parseObject(msg, SceneQueueDTO.class);
+            if (ObjectUtil.isEmpty(param.getSceneCode())) {
+                log.error("参数列表错误(缺少),格式不匹配,{}",param);
+                channel.basicAck(deliveryTag, false);
+                return;
+            }
+            sceneCode=param.getSceneCode();
+            WorkEntity workEntity=workService.findByNum(param.getSceneCode());
+            if (ObjectUtil.isEmpty(workEntity)&&param.getStatus()==0){
+                //初始化创建work表数据
+                workService.entityAdd2(param);
+                sendStartMq(param);
+            }if (ObjectUtil.isNotEmpty(workEntity)&&param.getStatus()!=1){
+                //修改状态
+                workEntity.setCalcStatus(param.getStatus());
+                if (ObjectUtil.isNotEmpty(param.getPwd())&&ObjectUtil.isEmpty(workEntity.getPassword())){
+                    workEntity.setPassword(param.getPwd());
+                    workEntity.setIsPassword(1);
+                }
+                if (ObjectUtil.isNotEmpty(param.getPayStatus())){
+                    workEntity.setPayStatus(param.getPayStatus());
+                }
+                workService.updateById(workEntity);
+                sendStartMq(param);
+            }else if (ObjectUtil.isNotEmpty(param.getSceneCode())&&param.getStatus()==1) {
+                //发送到处理队列
+                //rabbitMqProducerUtil.sendByWorkQueue(sceneQueueWork, msg);
+                //改造存入esc  mq_send_log
+                //        insert num ,  content ,type "pano"
+                MqSendLog mqSendLog = new MqSendLog();
+                mqSendLog.setNum(param.getSceneCode());
+                mqSendLog.setContent(msg);
+                mqSendLog.setType("pano");
+                mqSendLog.setCreateTime(new Date());
+                mqSendLogService.save(mqSendLog);
+                log.info("保存mqSendLog-数据库准备处理:{}",mqSendLog);
+            }
+
+        }catch (Exception e){
+            if (StrUtil.isNotEmpty(sceneCode)){
+                updateOssStatusJson(sceneCode,0);
+            }
+            log.error("场景sceneQueue报错{}",e.getMessage());
+            e.printStackTrace();
+
+        }finally {
+            channel.basicAck(deliveryTag, false);
+        }
+    }
+
+    private void updateOssStatusJson(String sceneCode, int status) throws Exception {
+        //修改OSS,status状态 scene_view_data/场景码/data/status.json
+        String statusJson = "scene_view_data/"+sceneCode+"/data/status.json";
+        Boolean exist=ossUtil.doesObjectExist("4dkankan",statusJson);
+        if (exist){
+            String fileContent = ossUtil.getFileContent("4dkankan", statusJson);
+            log.info("statusJson存在: {}",statusJson);
+            JSONObject statusJsonObj = JSONObject.parseObject(fileContent);
+            statusJsonObj.put("status",status);
+            ossUtil.uploadFileBytes("4dkankan",statusJson,statusJsonObj.toJSONString().getBytes(StandardCharsets.UTF_8));
+
+        }
+    }
+
+    private void sendStartMq(SceneQueueDTO param) {
+        RelicsSceneInitQueueDTO relicsSceneInitQueueDTO = new RelicsSceneInitQueueDTO();
+        relicsSceneInitQueueDTO.setSceneCode(param.getSceneCode());
+        relicsSceneInitQueueDTO.setLocation(param.getLocation());
+        relicsSceneInitQueueDTO.setCreateTime(param.getCreateTime());
+        relicsSceneInitQueueDTO.setPhoneNum(param.getPhoneNum());
+        relicsSceneInitQueueDTO.setUserId(param.getUserId());
+        relicsSceneInitQueueDTO.setSnCode(param.getSnCode());
+        relicsSceneInitQueueDTO.setStatus(param.getStatus());
+        relicsSceneInitQueueDTO.setSceneName(param.getSceneName());
+        relicsSceneInitQueueDTO.setShootCount(param.getShootCount());
+        relicsSceneInitQueueDTO.setSceneSource(param.getSceneSource());
+        relicsSceneInitQueueDTO.setPayStatus(param.getPayStatus());
+        rabbitMqProducerUtil.sendByWorkQueue(relicsInitQueue, relicsSceneInitQueueDTO);
+    }
+
+
+    private static final String CHARACTERS = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
+
+    public static String generateRandomId() {
+        Random random = new Random();
+        StringBuilder sb = new StringBuilder();
+        for (int i = 0; i < 8; i++) {
+            int index = random.nextInt(CHARACTERS.length());
+            sb.append(CHARACTERS.charAt(index));
+        }
+        return sb.toString();
+    }
+
+    public static String generateCustomId() {
+        return "s_" + generateRandomId();
+    }
+
+
+
+
+
+
+
+
+    public static void main(String[] args) {
+        List<String> list=new ArrayList<>();
+        list.add("scene_view_data/KJ-t-QPqp92mGf1c/images/pan/high/0.jpg");
+        list.add("scene_view_data/KJ-t-QPqp92mGf1c/images/pan/high/1.jpg");
+        list.add("scene_view_data/KJ-t-QPqp92mGf1c/images/pan/high/3.jpg");
+        list.add("scene_view_data/KJ-t-QPqp92mGf1c/images/pan/high/4.jpg");
+        //循环只打印文件是偶数的图片
+
+    }
+}

+ 592 - 0
720yun_fd_consumer/src/main/java/com/gis/listener/container/SceneWorkQueueListener.java

@@ -0,0 +1,592 @@
+package com.gis.listener.container;
+
+import cn.hutool.core.bean.BeanUtil;
+import cn.hutool.core.collection.CollUtil;
+import cn.hutool.core.io.FileUtil;
+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.filestorage.FileStorageTemplate;
+import com.gis.common.constant.ConfigConstant;
+import com.gis.common.mq.RabbitMqProducerUtil;
+import com.gis.common.util.CmdUtils;
+import com.gis.common.util.RandomUtils;
+import com.gis.common.util.RedisUtil;
+import com.gis.constant.RedisKey;
+import com.gis.constant.SysConstants;
+import com.gis.domain.dto.*;
+import com.gis.domain.entity.*;
+import com.gis.domain.vo.WorkNavigationVo;
+import com.gis.exception.BaseRuntimeException;
+import com.gis.oss.constant.CmdConstant;
+import com.gis.oss.util.FileAndOssUtil;
+import com.gis.oss.util.QrCodeUtils;
+import com.gis.receiver.QueueNameService;
+import com.gis.service.*;
+import com.rabbitmq.client.Channel;
+import lombok.extern.slf4j.Slf4j;
+import org.slf4j.MDC;
+import org.springframework.amqp.core.Message;
+import org.springframework.amqp.rabbit.listener.api.ChannelAwareMessageListener;
+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 javax.annotation.Resource;
+import java.io.File;
+import java.io.PrintWriter;
+import java.io.StringWriter;
+import java.nio.charset.StandardCharsets;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Date;
+import java.util.List;
+import java.util.concurrent.*;
+import java.util.concurrent.atomic.AtomicInteger;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+/**
+ * @author Xiewj
+ * @date 2025/3/19
+ */
+@Component
+@Slf4j
+public class SceneWorkQueueListener implements ChannelAwareMessageListener {
+    @Autowired
+    FodderService fodderService;
+    @Autowired
+    WorkService workService;
+    @Autowired
+    FileAndOssUtil fileAndOssUtil;
+    @Autowired
+    ConfigConstant configConstant;
+    @Autowired
+    QrCodeUtils qrCodeUtils;
+    @Autowired
+    ScenePanoService scenePanoService;
+    @Autowired
+    RabbitMqProducerUtil rabbitMqProducerUtil;
+    @Value("${queue.relics-init-queue}")
+    String relicsInitQueue;
+
+    @Value("${queue.scene-queue-work}")
+    String sceneQueueWork;
+    @Resource
+    private FileStorageTemplate ossUtil;
+    @Value("${domain.4dkk}")
+    public  String domain4dKK;
+    @Autowired
+    WorkCoverTypeService workCoverTypeService;
+
+    @Autowired
+    WorkLogoService workLogoService;
+
+    @Autowired
+    WorkOpeningTipService workOpeningTipService;
+
+    @Autowired
+    WorkOpeningAnimationService workOpeningAnimationService;
+
+    @Autowired
+    private WorkCustomMaskService workCustomMaskService;
+    @Autowired
+    QueueNameService queueNameService;
+    @Autowired
+    private WorkCustomButtonService workCustomButtonService;
+
+    @Autowired
+    private WorkNavigationSettingService workNavigationSettingService;
+    @Autowired
+    private WorkNavigationService workNavigationService;
+
+
+    @Autowired
+    IMqEcsService mqEcsService;
+    @Autowired
+    RedisUtil redisUtil;
+    @Override
+    public void onMessage(Message message, Channel channel) throws Exception {
+
+        if (ObjectUtils.isEmpty(message.getBody())) {
+            log.error("消息内容为空,退出构建,当前服务器id:{}" );
+            return;
+        }
+        String traceId = System.currentTimeMillis()+"";
+        MDC.put("TRACE_ID", traceId);
+        String sceneCode="";
+        long deliveryTag = message.getMessageProperties().getDeliveryTag();
+        //计算暂停锁,计算中锁。弹性伸缩控制服务使用
+        String modelingKey = String.format(RedisKey.modelingKey,SysConstants.hostName);
+        String stopKey = String.format(RedisKey.ecsStopKey,SysConstants.hostName);
+        String messageId = message.getMessageProperties().getMessageId();
+        String msg = new String(message.getBody(), StandardCharsets.UTF_8);
+
+
+
+        try {
+            log.error("服务实例:{} 正在构建!", SysConstants.hostName);
+            log.info("场景sceneQueueWork开始,队列名:{},id:{},deliveryTag:{},消息体:{}", queueNameService.getQueueName(), messageId,deliveryTag,msg);
+            //设置为计算超时时间过期
+            redisUtil.set(modelingKey,msg,SysConstants.modelTimeOut * 3600L,TimeUnit.SECONDS);
+            if(redisUtil.hasKey(stopKey)){
+                log.error("服务实例:{} 正在关闭,退出构建!", SysConstants.hostName);
+                redisUtil.delete(modelingKey);
+                channel.basicNack(deliveryTag, true, true);
+                return;
+            }
+            SceneQueueDTO param = JSONObject.parseObject(JSON.parse(msg).toString(), SceneQueueDTO.class);
+            if (ObjectUtil.isEmpty(param.getSceneCode())) {
+                log.error("参数列表错误(缺少),格式不匹配,{}",param);
+                return;
+            }
+            sceneCode=param.getSceneCode();
+            WorkEntity workEntity=workService.findByNum(param.getSceneCode());
+            if (ObjectUtil.isNotEmpty(param.getSceneCode())&&param.getStatus()==1){
+                updateOssStatusJson(param.getSceneCode(),0);
+
+                //计算完成处理
+                //1,下载场景的全景图 默认 。scene_view_data/panorama/目录下的全景图图片
+                workEntity.setAlgorithmTime(param.getAlgorithmTime());
+                workEntity.setCalcStatus(0);
+                if (ObjectUtil.isNotEmpty(param.getPayStatus())){
+                    workEntity.setPayStatus(param.getPayStatus());
+                }
+                if (ObjectUtil.isNotEmpty(param.getSceneSource())){
+                    workEntity.setSceneSource(param.getSceneSource());
+                }
+                if (ObjectUtil.isNotEmpty(param.getPwd())&&ObjectUtil.isEmpty(workEntity.getPassword())){
+                    workEntity.setPassword(param.getPwd());
+                    workEntity.setIsPassword(1);
+                }
+                workService.updateById(workEntity);
+                //清理旧数据
+                List<ScenePanoEntity> list = scenePanoService.findByWorkId(workEntity.getId());
+                for (ScenePanoEntity scenePanoEntity : list) {
+                    scenePanoEntity.setIsDelete(1);
+                    scenePanoEntity.setUpdateTime(new Date());
+                    scenePanoService.updateById(scenePanoEntity);
+                }
+                String visionOssKey="scene_view_data/"+param.getSceneCode()+"/images/vision.txt";
+
+                JSONArray sweepLocations = new JSONArray();
+                if (ossUtil.doesObjectExist("4dkankan",visionOssKey)){
+                    log.info("vision.txt存在: {}",visionOssKey);
+                    JSONObject visJson = JSONObject.parseObject(ossUtil.getFileContent("4dkankan",visionOssKey));
+                    if(visJson.containsKey("sweepLocations")){
+                        sweepLocations = visJson.getJSONArray("sweepLocations");
+                    }
+                }
+
+                //2,使用krpano工具生成全景图数据
+                List<InitWorkNavigationSceneDTO> scenes = new ArrayList<>();
+
+                for (int i = 0; i < sweepLocations.size(); i++) {
+                    JSONObject jsonObject = sweepLocations.getJSONObject(i);
+                    String uuid = jsonObject.getString("uuid");
+                    String id = jsonObject.getString("id");
+                    String ossKey="scene_view_data/"+param.getSceneCode()+"/images/panoramas/"+uuid+".jpg";
+                    InitWorkNavigationSceneDTO scene=new InitWorkNavigationSceneDTO();
+                    ScenePanoEntity scenePanoEntity = this.doSlice(traceId ,ossKey, param.getSceneCode(), workEntity.getId(),uuid+".jpg",uuid,id);
+                    //  "icon": "https://ossxiaoan.4dage.com/720yun_fd_manage/fd720_8nRkFlzpp/vtour/panos/fd720_8nRkFlzpp.tiles/thumb.jpg",
+                    //   "sceneCode": "fd720_8nRkFlzpp",
+                    // "sceneTitle": "0",
+                    //  "category": 1,
+                    //   "type": "pano",
+                    //  "id": "s_xId8vevp",
+                    scene.setIcon(scenePanoEntity.getIcon());
+                    scene.setType("pano");
+                    scene.setName(id);
+                    //id生成规则是 s_ 拼接,随机8位字符串,字母加数字组合,有大小写
+                    scene.setSceneCode(scenePanoEntity.getSceneCode());
+                    scenes.add(scene);
+                    if (i==0){
+                        workEntity.setIcon(scenePanoEntity.getIcon());
+                        workService.updateById(workEntity);
+                    }
+
+                }
+
+                log.info("场景切图完成组装json");
+                //修改为创建数据库
+                String shareUrl = configConstant.domain4dKK + "/panorama/showMobile.html?id=" + workEntity.getId();
+                String qrCode = qrCodeUtils.generateLogoQrCode(shareUrl, configConstant.serverBasePath, configConstant.ossBasePath, ossUtil.calculateUrl(""), workEntity.getId());
+                workEntity.setQrCode(qrCode);
+                workEntity.setShare(shareUrl);
+
+                //创建tour.xml
+                this.saveTour(workEntity.getId());
+
+                WorkAddDto workAddDto = new WorkAddDto();
+                workAddDto.setSceneDTOList(scenes);
+
+                this.initData(workAddDto, workEntity);
+
+                workEntity.setCalcStatus(1);
+                workService.updateById(workEntity);
+                sendEndMq(param);
+                updateOssStatusJson(param.getSceneCode(),1);
+            }
+            log.info("场景计算结束,队列名:{},id:{}", queueNameService.getQueueName(), messageId);
+
+
+        }catch (Exception e){
+            if (StrUtil.isNotEmpty(sceneCode)){
+                updateOssStatusJson(sceneCode,0);
+            }
+            log.error("场景sceneQueue报错{}",e.getMessage());
+            e.printStackTrace();
+        }finally {
+            //计算完毕,将当前系统构建状态改为false
+            redisUtil.delete(modelingKey);
+            channel.basicAck(deliveryTag, false);
+        }
+    }
+    private void sendEndMq(SceneQueueDTO param) {
+        RelicsSceneInitQueueDTO relicsSceneInitQueueDTO = new RelicsSceneInitQueueDTO();
+        relicsSceneInitQueueDTO.setSceneCode(param.getSceneCode());
+        relicsSceneInitQueueDTO.setLocation(param.getLocation());
+        relicsSceneInitQueueDTO.setAlgorithmTime(param.getAlgorithmTime());
+        relicsSceneInitQueueDTO.setCreateTime(param.getCreateTime());
+        relicsSceneInitQueueDTO.setPhoneNum(param.getPhoneNum());
+        relicsSceneInitQueueDTO.setUserId(param.getUserId());
+        relicsSceneInitQueueDTO.setSnCode(param.getSnCode());
+        relicsSceneInitQueueDTO.setStatus(param.getStatus());
+        relicsSceneInitQueueDTO.setSceneName(param.getSceneName());
+        relicsSceneInitQueueDTO.setShootCount(param.getShootCount());
+        relicsSceneInitQueueDTO.setSceneSource(param.getSceneSource());
+        relicsSceneInitQueueDTO.setPayStatus(param.getPayStatus());
+        rabbitMqProducerUtil.sendByWorkQueue(relicsInitQueue, relicsSceneInitQueueDTO);
+    }
+    private void updateOssStatusJson(String sceneCode, int status) throws Exception {
+        //修改OSS,status状态 scene_view_data/场景码/data/status.json
+        String statusJson = "scene_view_data/"+sceneCode+"/data/status.json";
+        Boolean exist=ossUtil.doesObjectExist("4dkankan",statusJson);
+        if (exist){
+            String fileContent = ossUtil.getFileContent("4dkankan", statusJson);
+            log.info("statusJson存在: {}",statusJson);
+            JSONObject statusJsonObj = JSONObject.parseObject(fileContent);
+            statusJsonObj.put("status",status);
+            ossUtil.uploadFileBytes("4dkankan",statusJson,statusJsonObj.toJSONString().getBytes(StandardCharsets.UTF_8));
+
+        }
+    }
+
+    private void initData(WorkAddDto workAddDto, WorkEntity entity){
+        workNavigationSettingService.removeByWorkId(entity.getId());
+        //添加默认分组
+        WorkNavigationDTO defaultGroup = WorkNavigationDTO.builder().parentId(0L).name("一级分组").sort(0).build();
+        defaultGroup.setWorkId(entity.getId());
+        WorkNavigationVo workNavigationVo = workNavigationSettingService.addGroup(defaultGroup);
+        List<WorkNavigationEntity> workNavigationEntities = BeanUtil.copyToList(workAddDto.getSceneDTOList(), WorkNavigationEntity.class);
+        AtomicInteger sort = new AtomicInteger(0);
+        workNavigationEntities.stream().forEach(v->{
+            v.setParentId(workNavigationVo.getId());
+            v.setWorkId(entity.getId());
+            v.setSort(sort.getAndAdd(1));
+        });
+        workNavigationService.saveBatch(workNavigationEntities);
+
+        //初始化遮罩数据
+        this.initMaskData(workNavigationEntities,entity.getId());
+
+        //初始化自定义按钮
+        this.initCustomButton(entity.getId());
+
+        //初始化开场动画设置
+        this.initOpenAnimation(entity.getId());
+
+        //初始化开场封面
+        this.initWorkCoverType(entity.getId());
+
+        //初始化自定义logo
+        this.initWorkLogo(entity.getId());
+
+        //初始化开场提示
+        this.initWorkOpeningTip(entity.getId());
+
+    }
+    public void initWorkOpeningTip(String workId){
+        WorkOpeningTipEntity entity = workOpeningTipService.getByWorkId(workId);
+        if (ObjectUtil.isNull(entity)){
+              entity = new WorkOpeningTipEntity();
+              entity.setWorkId(workId);
+              entity.setIsRemind(1);
+              entity.setRemindTime(1);
+              workOpeningTipService.saveOrUpdate(entity);
+        }
+
+    }
+    public void initWorkLogo(String workId){
+        WorkLogoEntity entity = workLogoService.getByWorkId(workId);
+        if (ObjectUtil.isNull(entity)){
+            entity = new WorkLogoEntity();
+            entity.setWorkId(workId);
+            entity.setIsLogo(1);
+            workLogoService.saveOrUpdate(entity);
+        }
+
+    }
+
+    public void initOpenAnimation(String workId){
+        WorkOpeningAnimationEntity entity = workOpeningAnimationService.getByWorkId(workId);
+        if (ObjectUtil.isNull(entity)){
+            entity = new WorkOpeningAnimationEntity();
+            entity.setIsShowOpeningAnimation(true);
+            entity.setOpeningAnimationType(1);
+            entity.setWorkId(workId);
+            workOpeningAnimationService.save(entity);
+        }
+
+    }
+    public void initWorkCoverType(String workId){
+        WorkCoverTypeEntity entity = workCoverTypeService.getByWorkId(workId);
+        if (ObjectUtil.isNull(entity)){
+            entity = new WorkCoverTypeEntity();
+            entity.setWorkId(workId);
+            entity.setCoverSelect("img");
+            entity.setCoverPcLoc("center");
+            entity.setCoverMoLoc("center");
+            entity.setCoverImgBac("colorFill");
+            entity.setImgColorSelec("#000000");
+            entity.setCoverImageInWay(1);
+            workCoverTypeService.saveOrUpdate(entity);
+        }
+
+    }
+
+
+    private void initCustomButton(String workId){
+        List<WorkCustomButtonEntity> workCustomButtonEntities = workCustomButtonService.listByWorkId(workId);
+        if (CollUtil.isEmpty(workCustomButtonEntities)){
+            WorkCustomButtonEntity phoneButton = new WorkCustomButtonEntity();
+            phoneButton.setWorkId(workId);
+            phoneButton.setIsShow(0);
+            phoneButton.setName("电话");
+            phoneButton.setType("phone");
+            phoneButton.setOpenMethod("_self");
+            phoneButton.setCreateTime(new Date());
+
+            WorkCustomButtonEntity linkButton = BeanUtil.toBean(phoneButton, WorkCustomButtonEntity.class);
+            linkButton.setName("链接");
+            workCustomButtonService.saveBatch(Arrays.asList(phoneButton, linkButton));
+        }
+
+    }
+
+    private void initMaskData(List<WorkNavigationEntity> workNavigations, String workId){
+        List<WorkCustomMaskEntity> workCustomMaskEntities = workCustomMaskService.listByWorkId(workId);
+        if(CollUtil.isEmpty(workCustomMaskEntities)) {
+            List<WorkCustomMaskEntity> list = new ArrayList<>();
+            workNavigations.stream().forEach(v -> {
+                WorkCustomMaskEntity sky = new WorkCustomMaskEntity();
+                sky.setWorkId(v.getWorkId());
+                sky.setNavigationId(v.getId());
+                sky.setIsShow(true);
+                sky.setType("sky");
+                sky.setAntidistorted(true);
+                sky.setScale(1D);
+                list.add(sky);
+
+                WorkCustomMaskEntity earth = BeanUtil.toBean(sky, WorkCustomMaskEntity.class);
+                earth.setType("earth");
+                earth.setIsShow(false);
+                list.add(earth);
+            });
+            if (CollUtil.isNotEmpty(list)) {
+                workCustomMaskService.saveBatch(list);
+            }
+        }
+    }
+    private ScenePanoEntity doSlice(String traceId, String item, String num, String workId, String imgName, String uuid, String id){
+        ScenePanoEntity entity=scenePanoService.findByWorkIdAndName(workId,imgName);
+        String sceneCode ="";
+        String newName = "";
+        String filePath = "";
+        if (ObjectUtil.isEmpty(entity)) {
+            //未生成
+            sceneCode = RandomUtils.getSceneCode("fd720_");
+            newName = sceneCode + ".jpg";
+            filePath = configConstant.serverBasePath + sceneCode+ "/" + newName;
+            ossUtil.downloadFile("4dkankan",item,filePath );
+
+            entity = new ScenePanoEntity();
+            entity.setFilePath(filePath);
+            entity.setFileName(FileUtil.getName(filePath));
+            entity.setSceneCode(sceneCode);
+            entity.setNum(num);
+            entity.setOssPath(item);
+            entity.setName(imgName);
+            entity.setWorkId(workId);
+            entity.setVisid(id);
+            entity.setUuid(uuid);
+            long size = FileUtil.size(new File(filePath));
+            size = size / 1024;
+            log.info("fileSize: " + size);
+            entity.setFileSize(size + "");
+
+            scenePanoService.save(entity);
+        }else {
+            entity.setStatus(0);
+
+            filePath = entity.getFilePath();
+            sceneCode = entity.getSceneCode();
+            boolean exist = FileUtil.exist(filePath);
+            if (exist){
+                FileUtil.del(filePath);
+            }
+            if (filePath.endsWith(".jpg")){
+                String parent = FileUtil.getParent(filePath, 1);
+                FileUtil.del(parent);
+            }
+
+
+            log.info("生成过,重新下载");
+            ossUtil.downloadFile("4dkankan",item,filePath );
+            log.info("下载完成重新切图");
+            long size = FileUtil.size(new File(filePath));
+            size = size / 1024;
+            log.info("fileSize: " + size);
+            entity.setFileSize(size + "");
+            scenePanoService.updateById(entity);
+
+        }
+
+
+        log.info("切图流程开始 : " + filePath);
+        long start = System.currentTimeMillis();
+
+        String cmd = CmdConstant.PANO_KRPANO + filePath;
+        // 超时处理机制
+        final ExecutorService exec = Executors.newFixedThreadPool(1);
+        Callable<String> call = new Callable<String>() {
+            @Override
+            public String call() throws Exception {
+                MDC.put("TRACE_ID", traceId);
+                CmdUtils.callLine(cmd, 200);
+                long end = System.currentTimeMillis();
+                log.info("切图完成耗时: {} s" ,(end-start)/1000);
+                return "执行完成";
+            }
+        };
+        // 超时回调
+        Future<String> future = exec.submit(call);
+        try {
+            String obj = future.get(20, TimeUnit.MINUTES); //任务处理超时时间设为 3分钟
+            entity.setStatus(3);
+            String tourXmlScene = this.getTourXmlScene(sceneCode);
+            entity.setTour(tourXmlScene);
+            // 上传切图
+            this.uploadOss(sceneCode);
+            String ossUrl = ossUtil.calculateUrl("") + configConstant.ossBasePath + sceneCode+"/vtour/panos/"+sceneCode+".tiles/thumb.jpg";
+            log.info("切图预览图ossUrl: {}",ossUrl);
+            entity.setIcon(ossUrl);
+            log.info("任务成功返回: " + obj);
+
+        } catch (InterruptedException e) {
+            e.printStackTrace();
+            entity.setStatus(2);
+            StringWriter trace=new StringWriter();
+            log.error(trace.toString());
+            log.error("异常了 InterruptedException");
+        } catch (ExecutionException | BaseRuntimeException e) {
+            e.printStackTrace();
+            StringWriter trace=new StringWriter();
+            e.printStackTrace(new PrintWriter(trace));
+            log.error("超时了 1");
+            // 异常日志要打印,不然不会出现在日志文件中,只会出现在控制台
+            log.error(trace.toString());
+            entity.setStatus(2);
+            future.cancel(true);
+        } catch (TimeoutException e) {
+            e.printStackTrace();
+            StringWriter trace=new StringWriter();
+            e.printStackTrace(new PrintWriter(trace));
+            log.error("超时了 2");
+            log.error(trace.toString());
+            entity.setStatus(2);
+            future.cancel(true);
+        } finally {
+            scenePanoService.updateById(entity);
+            log.info("切图流程, 更新数据库完成 : ");
+        }
+        log.info("切图流程结束 : ");
+        return entity;
+    }
+    /**
+     * 更新 tour.xml
+     * @param id
+     */
+    private void saveTour(String id) {
+        List<ScenePanoEntity> list = scenePanoService.findByWorkId(id);
+        // 读取tour.xml模板
+        String baseTour = getBaseTour();
+        StringBuilder builder = new StringBuilder();
+        builder.append(baseTour).append("\r\n");
+        for (ScenePanoEntity entity : list) {
+            String tour = entity.getTour();
+            builder.append(tour).append("\r\n");
+        }
+
+        // 添加结束标签
+        builder.append("</krpano>");
+
+        String tourPath = configConstant.serverBasePath + id + "/tour.xml";
+        FileUtil.writeUtf8String(builder.toString(), tourPath);
+        log.info("作品tour.xml写入完成");
+
+        String ossKeyPath = configConstant.ossBasePath + id + "/tour.xml";
+        ossUtil.uploadFile( ossKeyPath,tourPath);
+        log.info("tour.xml上传完成 : {}", ossKeyPath);
+    }
+
+    private String getBaseTour(){
+        String baseTourPath = configConstant.serverBasePath + "baseData/tour.xml";
+        String s = FileUtil.readString(baseTourPath, "utf-8");
+        // 结束标签置空, 方便操作
+        s = s.replace("</krpano>", "");
+        return s;
+    }
+    private void uploadOss(String sceneCode) {
+        long start = System.currentTimeMillis();
+        String filePath = "/mnt/720yun_fd_manage_data/" + sceneCode;
+        String ossKey = "720yun_fd_manage/" + sceneCode;
+        fileAndOssUtil.uploadBySh(filePath, ossKey);
+        long end = System.currentTimeMillis();
+        log.info("切图上传完成, 耗时:{} s" , (end-start)/1000 );
+    }
+
+    // 获取切图后的tour.xml
+    private String getTourXmlScene(String code) {
+        log.info("处理tour.xml");
+        String tourPath = configConstant.serverBasePath + code + "/vtour/tour.xml";
+        log.info("tourPath: {}", tourPath);
+        BaseRuntimeException.isTrue(!FileUtil.isFile(tourPath), null, code + "_tour.xml文件不存在");
+
+        String tour = FileUtil.readUtf8String(tourPath);
+        tour = this.extractSceneTag(tour);
+        String trim = StrUtil.trim(tour);
+        // log.info("trim: {}", trim);
+        BaseRuntimeException.isTrue(StrUtil.isAllBlank(trim), null, code + "_tour.xml文件不存在");
+
+        // 2022-09-15 加入相对路径
+        String basePath = "%CURRENTXML%../" + code + "/vtour/panos/";
+        trim = trim.replaceAll("panos/", basePath);
+
+        return trim;
+    }
+    public static String extractSceneTag(String xmlString) {
+        Pattern pattern = Pattern.compile("<scene.*?</scene>", Pattern.DOTALL);
+        Matcher matcher = pattern.matcher(xmlString);
+
+        if (matcher.find()) {
+            return matcher.group();
+        }
+
+        return "";
+    }
+
+}

+ 45 - 0
720yun_fd_consumer/src/main/java/com/gis/receiver/QueueNameService.java

@@ -0,0 +1,45 @@
+package com.gis.receiver;
+
+import cn.hutool.core.util.StrUtil;
+import com.gis.constant.SysConstants;
+import com.gis.domain.entity.MqEcs;
+import com.gis.service.IMqEcsService;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.stereotype.Service;
+
+/**
+ * @author Xiewj
+ * @date 2025/3/18
+ */
+@Service
+@Slf4j
+public class QueueNameService  {
+
+    @Value("${queue.scene-queue-work}")
+    String queue ;
+    @Autowired
+    IMqEcsService mqEcsService;
+    @Value("${mq.listener.dynamic}")
+    private boolean isDynamic;
+    public String getQueueName(){
+        String queueName = queue;
+        if (!isDynamic){
+            log.info("不是弹性服务,应该获取默认队列去启动,监听队列名为:{}",queueName);
+            return queue;
+        }
+        if(StrUtil.isBlank(SysConstants.hostName)){
+            log.info("获取hostName失败,监听队列名为:{}",queueName);
+            return queueName;
+        }
+        MqEcs mqEcs = mqEcsService.getByHostName(SysConstants.hostName);
+        if(mqEcs != null ){
+            queueName = mqEcs.getQueueName();
+            log.info("获取hostNam成功,监听队列名为:{}",queueName);
+            return queueName;
+        }
+        log.info("获取hostName失败,监听默认队列名为:{}",queueName);
+        return queueName;
+    }
+}

+ 63 - 0
720yun_fd_consumer/src/main/resources/application-dev.yml

@@ -0,0 +1,63 @@
+logging:
+    config: classpath:logback-spring.xml
+    fdkk:
+        level: INFO
+        maxHistory: 180
+    level:
+        com:
+            gis: info
+    path: /root/data/${project.name}_log
+oss:
+    bucket: oss-xiaoan
+    domain: https://ossxiaoan.4dage.com/
+    file:
+        path: 720yun_fd_manage/
+    key: LTAIUrvuHqj8pvry
+    point: http://oss-cn-shenzhen-internal.aliyuncs.com
+    secrecy: JLOVl0k8Ke0aaM8nLMMiUAZ3EiiqI4
+    type: oss
+server:
+    file:
+        path: /mnt/720yun_fd_manage_data/
+spring:
+    datasource:
+        driver-class-name: com.mysql.cj.jdbc.Driver
+        druid:
+            initial-size: 5
+            max-active: 20
+            max-evictable-idle-time-millis: 90000
+            max-wait: 60000
+            min-evictable-idle-time-millis: 30000
+            min-idle: 10
+            password: 4dkk2021testproject%
+            stat-view-servlet:
+                enabled: true
+            test-on-borrow: false
+            test-on-return: false
+            test-while-idle: true
+            time-between-eviction-runs-millis: 60000
+            url: jdbc:mysql://127.0.0.1:3306/720yun_fd_manage?serverTimezone=GMT%2B8&useUnicode=true&characterEncoding=utf8&characterSetResults=utf8
+            username: root
+            validation-query: SELECT 1 FROM DUAL
+            web-stat-filter:
+                enabled: true
+        type: com.alibaba.druid.pool.DruidDataSource
+    rabbitmq:
+        address: 127.0.0.1:5672
+        connection-timeout: 15000
+        password: admin123
+        publisher-confirms: true
+        publisher-returns: true
+        template:
+            mandatory: true
+        username: admin
+        virtual-host: /
+tlog:
+    enable-invoke-time-print: true
+queue:
+    scene-queue: queue-pano-scene
+    do-slice-queue: queue-do-slice
+    relics-init-queue: relics-init-queue
+    relics-update-name-queue: relics-update-name-queue
+    pano-migrate-scene-queue: pano-migrate-scene-queue
+    pano-paystatus-scene-queue: pano-paystatus-scene-queue

+ 87 - 0
720yun_fd_consumer/src/main/resources/application-loc-site.yml

@@ -0,0 +1,87 @@
+domain:
+    4dkk: https://test.4dkankan.com
+logging:
+    config: classpath:logback-spring.xml
+    fdkk:
+        level: INFO
+        maxHistory: 180
+    file:
+        path: E:/javaProject/${project.name}_log
+    level:
+        com:
+            gis: info
+filestorage:
+    active: oss
+    oss:
+        endpoint: http://oss-cn-shenzhen.aliyuncs.com
+        internal-endpoint: http://oss-cn-shenzhen.aliyuncs.com
+        access-key: LTAI5tJwboCj3r4vUNkSmbyX
+        access-key-secret: meDy7VYAWbg8kZCKsoUZcIYQxigWOy
+        bucket: oss-xiaoan
+        bucket-custom-domain:
+            oss-xiaoan: https://ossxiaoan.4dage.com/
+            4dkankan: https://4dkk.4dage.com/
+        full-path: true
+server:
+    file:
+        path: i:\test\ngin\${project.name}_data\
+spring:
+    datasource:
+        type: com.alibaba.druid.pool.DruidDataSource
+        dynamic:
+            primary: db1
+            strict: false
+            datasource:
+                db1:
+                    driver-class-name: com.mysql.cj.jdbc.Driver
+                    url: jdbc:mysql://120.25.146.52:13306/720yun_fd_manage?serverTimezone=GMT%2B8&useUnicode=true&characterEncoding=utf8&characterSetResults=utf8
+                    username: root
+                    password: JK123456%JIK
+                db2:
+                    driver-class-name: com.mysql.cj.jdbc.Driver
+                    url: jdbc:mysql://120.24.144.164:3306/4dkankan_v4?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=Asia/Shanghai&allowMultiQueries=true
+                    username: root
+                    password: 4Dage@4Dage#@168
+    rabbitmq:
+        host: 120.24.144.164
+        port: 5672
+        username: admin
+        password: adminv41234
+        virtual-host: 4dkankan
+        connection-timeout: 0
+        listener:
+            simple:
+                prefetch: 1
+                max-concurrency: 2
+                acknowledge-mode: manual #开启消费者手动确认
+        #开启消息投递确认机制
+        publisher-confirm-type: correlated
+    redis:
+        database: 0
+        host: 120.24.144.164
+        jedis:
+            pool:
+                max-active: 8
+                max-idle: 8
+                max-wait: -1ms
+                min-idle: 0
+        password: bgh0cae240
+        port: 6379
+        timeout: 3000ms
+tlog:
+    enable-invoke-time-print: true
+queue:
+    scene-queue: queue-pano-scene
+    do-slice-queue: queue-do-slice
+    relics-init-queue: relics-init-queue
+    relics-update-name-queue: relics-update-name-queue
+    pano-migrate-scene-queue: pano-migrate-scene-queue
+    pano-paystatus-scene-queue: pano-paystatus-scene-queue
+    scene-queue-work: queue-pano-scene-work-A
+config:
+    bashPath: ${project.name}/
+mq:
+    listener:
+        dynamic: ${Dynamic}
+hostName:
+    filePath: I:\720_host\hosts.txt

+ 63 - 0
720yun_fd_consumer/src/main/resources/application-loc.yml

@@ -0,0 +1,63 @@
+logging:
+    config: classpath:logback-spring.xml
+    fdkk:
+        level: INFO
+        maxHistory: 180
+    level:
+        com:
+            gis: debug
+    path: E:/javaProject/${project.name}_log
+oss:
+    bucket: oss-xiaoan
+    domain: http://ossxiaoan.4dage.com/
+    file:
+        path: cms_pano_fcb//
+    key: LTAIUrvuHqj8pvry
+    point: http://oss-cn-shenzhen.aliyuncs.com
+    secrecy: JLOVl0k8Ke0aaM8nLMMiUAZ3EiiqI4
+    type: oss
+server:
+    file:
+        path: F:\test\ngin\${project.name}_data\
+spring:
+    datasource:
+        driver-class-name: com.mysql.cj.jdbc.Driver
+        druid:
+            initial-size: 5
+            max-active: 20
+            max-evictable-idle-time-millis: 90000
+            max-wait: 60000
+            min-evictable-idle-time-millis: 30000
+            min-idle: 10
+            password: root
+            stat-view-servlet:
+                enabled: true
+            test-on-borrow: false
+            test-on-return: false
+            test-while-idle: true
+            time-between-eviction-runs-millis: 60000
+            url: jdbc:mysql://localhost:3306/cms_pano_manage_fd?serverTimezone=GMT%2B8&useUnicode=true&characterEncoding=utf8&characterSetResults=utf8
+            username: root
+            validation-query: SELECT 1 FROM DUAL
+            web-stat-filter:
+                enabled: true
+        type: com.alibaba.druid.pool.DruidDataSource
+    rabbitmq:
+        address: 127.0.0.1:5672
+        connection-timeout: 15000
+        password: guest
+        publisher-confirms: true
+        publisher-returns: true
+        template:
+            mandatory: true
+        username: guest
+        virtual-host: /
+tlog:
+    enable-invoke-time-print: true
+queue:
+    scene-queue: queue-pano-scene
+    do-slice-queue: queue-do-slice
+    relics-init-queue: relics-init-queue
+    relics-update-name-queue: relics-update-name-queue
+    pano-migrate-scene-queue: pano-migrate-scene-queue
+    pano-paystatus-scene-queue: pano-paystatus-scene-queue

+ 56 - 0
720yun_fd_consumer/src/main/resources/application-locSitAws.yml

@@ -0,0 +1,56 @@
+logging:
+    config: classpath:logback-spring.xml
+    fdkk:
+        level: INFO
+        maxHistory: 180
+    level:
+        com:
+            gis: info
+    path: /root/data/${project.name}_log
+oss:
+    bucket: test-4dkankan
+    domain: https://testeurs3.4dkankan.com/
+    file:
+        path: 720yun_fd_manage/
+    key: LTAIUrvuHqj8pvry
+    point: http://oss-cn-shenzhen-internal.aliyuncs.com
+    secrecy: JLOVl0k8Ke0aaM8nLMMiUAZ3EiiqI4
+    type: aws
+server:
+    file:
+        path: /mnt/720yun_fd_manage_data/
+spring:
+    datasource:
+        driver-class-name: com.mysql.cj.jdbc.Driver
+        druid:
+            initial-size: 5
+            max-active: 20
+            max-evictable-idle-time-millis: 90000
+            max-wait: 60000
+            min-evictable-idle-time-millis: 30000
+            min-idle: 10
+            password: 4dkk2021testproject%
+            stat-view-servlet:
+                enabled: true
+            test-on-borrow: false
+            test-on-return: false
+            test-while-idle: true
+            time-between-eviction-runs-millis: 60000
+            url: jdbc:mysql://8.135.106.227:3306/720yun_fd_manage?serverTimezone=GMT%2B8&useUnicode=true&characterEncoding=utf8&characterSetResults=utf8&useSSL=false
+            username: root
+            validation-query: SELECT 1 FROM DUAL
+            web-stat-filter:
+                enabled: true
+        type: com.alibaba.druid.pool.DruidDataSource
+    rabbitmq:
+        address: 127.0.0.1:5672
+        connection-timeout: 15000
+        password: 4dagecui2019$
+        publisher-confirms: true
+        publisher-returns: true
+        template:
+            mandatory: true
+        username: guest
+        virtual-host: /
+tlog:
+    enable-invoke-time-print: true

+ 75 - 0
720yun_fd_consumer/src/main/resources/application-locsitSD.yml

@@ -0,0 +1,75 @@
+domain:
+    4dkk: https://192.168.0.64
+logging:
+    config: classpath:logback-spring.xml
+    fdkk:
+        level: INFO
+        maxHistory: 180
+    file:
+        path: /home/backend/4dkankan_v4/qjkankan/logs/${project.name}_log
+    level:
+        com:
+            gis: info
+filestorage:
+    active: minio
+    minio:
+        endpoint: http://192.168.0.64:13008
+        internal-endpoint: http://4dkankan-mix3d-minio:13008
+        access-key: rohVjfYyZRJH0ovNEVWg
+        access-key-secret: ffTI2PHAzDSfV6WNElOh6S2Qdtwpux0D1nssmK9g
+        bucket: qjkankan
+        bucket-custom-domain:
+            qjkankan: http://${FILE_STORAGE_IP}
+        full-path: false
+server:
+    file:
+        path: /mnt/720yun_fd_manage_data/
+spring:
+    datasource:
+        driver-class-name: com.mysql.cj.jdbc.Driver
+        druid:
+            initial-size: 5
+            max-active: 20
+            max-evictable-idle-time-millis: 90000
+            max-wait: 60000
+            min-evictable-idle-time-millis: 30000
+            min-idle: 10
+            password: 4dkk2024cuikuan%
+            stat-view-servlet:
+                enabled: true
+            test-on-borrow: false
+            test-on-return: false
+            test-while-idle: true
+            time-between-eviction-runs-millis: 60000
+            url: jdbc:mysql://192.168.0.64:13001/720yun_fd_manage?serverTimezone=GMT%2B8&useUnicode=true&characterEncoding=utf8&characterSetResults=utf8
+            username: root
+            validation-query: SELECT 1 FROM DUAL
+            web-stat-filter:
+                enabled: true
+        type: com.alibaba.druid.pool.DruidDataSource
+    rabbitmq:
+        host: 192.168.0.64
+        port: 13006
+        username: root
+        password: JHroot2024
+        virtual-host: 4dkankan
+        connection-timeout: 0
+        listener:
+            simple:
+                prefetch: 1
+                max-concurrency: 2
+                acknowledge-mode: manual #开启消费者手动确认
+        #开启消息投递确认机制
+        publisher-confirm-type: correlated
+tlog:
+    enable-invoke-time-print: true
+config:
+    bashPath: ${project.name}/
+queue:
+    scene-queue: queue-pano-scene
+    do-slice-queue: queue-do-slice
+    relics-init-queue: relics-init-queue
+    relics-update-name-queue: relics-update-name-queue
+    pano-migrate-scene-queue: pano-migrate-scene-queue
+    pano-paystatus-scene-queue: pano-paystatus-scene-queue
+    scene-queue-work: queue-pano-scene-work-A

+ 89 - 0
720yun_fd_consumer/src/main/resources/application-pro.yml

@@ -0,0 +1,89 @@
+domain:
+    4dkk: https://www.4dkankan.com
+logging:
+    config: classpath:logback-spring.xml
+    fdkk:
+        level: INFO
+        maxHistory: 180
+    level:
+        com:
+            gis: info
+    path: /root/log/${project.name}_log
+filestorage:
+    active: oss
+    oss:
+        endpoint: http://oss-cn-shenzhen.aliyuncs.com
+        internal-endpoint: http://oss-cn-shenzhen-internal.aliyuncs.com
+        access-key: LTAI5tSkKQbEmxxuTbPtHqK6
+        access-key-secret: JI21tOnZbJuqt5NDRcQq2qvAUA4KTf
+        bucket: 4dkankan
+        bucket-custom-domain:
+            oss-xiaoan: https://ossxiaoan.4dage.com/
+            4dkankan: https://4dkk.4dage.com/
+        full-path: true
+server:
+    file:
+        path: /mnt/720yun_fd_manage_data/
+spring:
+    datasource:
+        driver-class-name: com.mysql.cj.jdbc.Driver
+        druid:
+            initial-size: 5
+            max-active: 20
+            max-evictable-idle-time-millis: 90000
+            max-wait: 60000
+            min-evictable-idle-time-millis: 30000
+            min-idle: 10
+            password: JK20220120&JIK
+            stat-view-servlet:
+                enabled: true
+            test-on-borrow: false
+            test-on-return: false
+            test-while-idle: true
+            time-between-eviction-runs-millis: 60000
+            url: jdbc:mysql://172.18.157.42:13306/720yun_fd_manage?serverTimezone=GMT%2B8&useUnicode=true&characterEncoding=utf8&characterSetResults=utf8
+            username: laser
+            validation-query: SELECT 1 FROM DUAL
+            web-stat-filter:
+                enabled: true
+        type: com.alibaba.druid.pool.DruidDataSource
+    rabbitmq:
+        host: 172.18.157.42
+        port: 5672
+        username: guest
+        password: guest
+        virtual-host: 4dkankan
+        connection-timeout: 0
+        listener:
+            simple:
+                prefetch: 1
+                max-concurrency: 10
+                acknowledge-mode: manual #开启消费者手动确认
+            direct:
+                acknowledge-mode: manual #开启消费者手动确认
+        #开启消息投递确认机制
+        publisher-confirm-type: correlated
+    redis:
+        database: 0
+        host: r-wz9owsphxqwi4ztqlf.redis.rds.aliyuncs.com
+        jedis:
+            pool:
+                max-active: 8
+                max-idle: 8
+                max-wait: -1ms
+                min-idle: 0
+        password: 3oo19bgh0cae2406&
+        port: 6379
+        timeout: 3000ms
+tlog:
+    enable-invoke-time-print: true
+queue:
+    scene-queue: queue-pano-scene
+    do-slice-queue: queue-do-slice
+    relics-init-queue: relics-init-queue
+    relics-update-name-queue: relics-update-name-queue
+    pano-migrate-scene-queue: pano-migrate-scene-queue
+    pano-paystatus-scene-queue: pano-paystatus-scene-queue
+    scene-queue-work: queue-pano-scene-work-A
+config:
+    bashPath: 720yun_fd_manage/

+ 89 - 0
720yun_fd_consumer/src/main/resources/application-proAws.yml

@@ -0,0 +1,89 @@
+domain:
+    4dkk: https://eur.4dkankan.com
+logging:
+    config: classpath:logback-spring.xml
+    fdkk:
+        level: INFO
+        maxHistory: 180
+    level:
+        com:
+            gis: info
+    path: /root/data/${project.name}_log
+filestorage:
+    active: aws
+    aws:
+        endpoint: http://eurs3.4dkankan.com
+        internal-endpoint: http://eurs3.4dkankan.com
+        access-key: AKIAWCV5QFZ3ZNELKYUY
+        access-key-secret: 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
+        bucket: 4dkankan
+        bucket-custom-domain:
+            4dkankan: https://eurs3.4dkankan.com
+server:
+    file:
+        path: /mnt/720yun_fd_manage_data/
+service:
+    ip: 172.31.47.163
+spring:
+    datasource:
+        driver-class-name: com.mysql.cj.jdbc.Driver
+        druid:
+            initial-size: 5
+            max-active: 20
+            max-evictable-idle-time-millis: 90000
+            max-wait: 60000
+            min-evictable-idle-time-millis: 30000
+            min-idle: 10
+            password: JK20220120%JIK
+            stat-view-servlet:
+                enabled: true
+            test-on-borrow: false
+            test-on-return: false
+            test-while-idle: true
+            time-between-eviction-runs-millis: 60000
+            url: jdbc:mysql://${service.ip}:13306/720yun_fd_manage?serverTimezone=GMT%2B8&useUnicode=true&characterEncoding=utf8&characterSetResults=utf8&useSSL=false
+            username: root
+            validation-query: SELECT 1 FROM DUAL
+            web-stat-filter:
+                enabled: true
+        type: com.alibaba.druid.pool.DruidDataSource
+    rabbitmq:
+        host: ${service.ip}
+        port: 5672
+        username: guest
+        password: guest
+        virtual-host: 4dkankan
+        connection-timeout: 0
+        listener:
+            simple:
+                prefetch: 1
+                max-concurrency: 10
+                acknowledge-mode: manual #�����������ֶ�ȷ��
+            direct:
+                acknowledge-mode: manual #�����������ֶ�ȷ��
+        #������ϢͶ��ȷ�ϻ���
+        publisher-confirm-type: correlated
+    redis:
+        database: 0
+        host: ${service.ip}
+        jedis:
+            pool:
+                max-active: 8
+                max-idle: 8
+                max-wait: -1ms
+                min-idle: 0
+        password: ''
+        port: 6379
+        timeout: 3000ms
+tlog:
+    enable-invoke-time-print: true
+queue:
+    scene-queue: queue-pano-scene
+    do-slice-queue: queue-do-slice
+    relics-init-queue: relics-init-queue
+    relics-update-name-queue: relics-update-name-queue
+    pano-migrate-scene-queue: pano-migrate-scene-queue
+    pano-paystatus-scene-queue: pano-paystatus-scene-queue
+    scene-queue-work: queue-pano-scene-work-A
+config:
+    bashPath: 720yun_fd_manage/

+ 59 - 0
720yun_fd_consumer/src/main/resources/application-proSD.yml

@@ -0,0 +1,59 @@
+logging:
+    config: classpath:logback-spring.xml
+    fdkk:
+        level: INFO
+        maxHistory: 180
+    level:
+        com:
+            gis: info
+    path: /root/data/${project.name}_log
+filestorage:
+    active: minio
+    minio:
+        endpoint: http://${FILE_STORAGE_IP}:9001
+        internal-endpoint: http://${FILE_STORAGE_IP}:9001
+        access-key: FYxjWFQzycMhdxUXDVYU
+        access-key-secret: TRQJGvWk4SSZXFg1BDQ3jFcTMeXKAb0i4W59dxYZ
+        bucket: laser-data
+        bucket-custom-domain:
+            laser-data: http://${FILE_STORAGE_IP}
+        full-path: false
+server:
+    file:
+        path: /mnt/720yun_fd_manage_data/
+spring:
+    datasource:
+        driver-class-name: com.mysql.cj.jdbc.Driver
+        druid:
+            initial-size: 5
+            max-active: 20
+            max-evictable-idle-time-millis: 90000
+            max-wait: 60000
+            min-evictable-idle-time-millis: 30000
+            min-idle: 10
+            password: JK20220120%JIK
+            stat-view-servlet:
+                enabled: true
+            test-on-borrow: false
+            test-on-return: false
+            test-while-idle: true
+            time-between-eviction-runs-millis: 60000
+            url: jdbc:mysql://127.0.0.1:3306/720yun_fd_manage?serverTimezone=GMT%2B8&useUnicode=true&characterEncoding=utf8&characterSetResults=utf8&useSSL=false
+            username: root
+            validation-query: SELECT 1 FROM DUAL
+            web-stat-filter:
+                enabled: true
+        type: com.alibaba.druid.pool.DruidDataSource
+    rabbitmq:
+        address: 127.0.0.1:5672
+        connection-timeout: 15000
+        password: 123456
+        publisher-confirms: true
+        publisher-returns: true
+        template:
+            mandatory: true
+        username: admin
+        virtual-host: /
+tlog:
+    enable-invoke-time-print: true
+    pano-migrate-scene-queue: pano-migrate-scene-queue

+ 89 - 0
720yun_fd_consumer/src/main/resources/application-sit.yml

@@ -0,0 +1,89 @@
+domain:
+    4dkk: https://test.4dkankan.com
+logging:
+    config: classpath:logback-spring.xml
+    fdkk:
+        level: INFO
+        maxHistory: 180
+    level:
+        com:
+            gis: info
+    file:
+        path: /root/log/${project.name}_log
+filestorage:
+    active: oss
+    oss:
+        endpoint: http://oss-cn-shenzhen.aliyuncs.com
+        internal-endpoint: http://oss-cn-shenzhen-internal.aliyuncs.com
+        access-key: LTAI5tJwboCj3r4vUNkSmbyX
+        access-key-secret: meDy7VYAWbg8kZCKsoUZcIYQxigWOy
+        bucket: oss-xiaoan
+        bucket-custom-domain:
+            oss-xiaoan: https://ossxiaoan.4dage.com/
+            4dkankan: https://4dkk.4dage.com/
+        full-path: true
+server:
+    file:
+        path: /mnt/720yun_fd_manage_data/
+spring:
+    datasource:
+        type: com.alibaba.druid.pool.DruidDataSource
+        dynamic:
+            primary: db1
+            strict: false
+            datasource:
+                db1:
+                    driver-class-name: com.mysql.cj.jdbc.Driver
+                    url: jdbc:mysql://172.18.156.41:13306/720yun_fd_manage?serverTimezone=GMT%2B8&useUnicode=true&characterEncoding=utf8&characterSetResults=utf8
+                    username: root
+                    password: JK123456%JIK
+                db2:
+                    driver-class-name: com.mysql.cj.jdbc.Driver
+                    url: jdbc:mysql://172.18.156.39:3306/4dkankan_v4?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=Asia/Shanghai&allowMultiQueries=true
+                    username: root
+                    password: 4Dage@4Dage#@168
+    rabbitmq:
+        host: 172.18.156.39
+        port: 5672
+        username: admin
+        password: adminv41234
+        virtual-host: 4dkankan
+        connection-timeout: 0
+        listener:
+            simple:
+                prefetch: 1
+                max-concurrency: 2
+                acknowledge-mode: manual #开启消费者手动确认
+        #开启消息投递确认机制
+        publisher-confirm-type: correlated
+    redis:
+        database: 0
+        host: 172.18.156.39
+        jedis:
+            pool:
+                max-active: 8
+                max-idle: 8
+                max-wait: -1ms
+                min-idle: 0
+        password: bgh0cae240
+        port: 6379
+        timeout: 3000ms
+tlog:
+    enable-invoke-time-print: true
+queue:
+    scene-queue: queue-pano-scene
+    do-slice-queue: queue-do-slice
+    relics-init-queue: relics-init-queue
+    relics-update-name-queue: relics-update-name-queue
+    pano-migrate-scene-queue: pano-migrate-scene-queue
+    pano-paystatus-scene-queue: pano-paystatus-scene-queue
+    scene-queue-work: queue-pano-scene-work-A
+
+config:
+    bashPath: 720yun_fd_manage/
+# application.yml
+mq:
+ listener:
+    dynamic: ${Dynamic}
+hostName:
+    filePath: /opt/hosts/hosts.txt

+ 85 - 0
720yun_fd_consumer/src/main/resources/application-sitAws.yml

@@ -0,0 +1,85 @@
+domain:
+    4dkk: https://testeur.4dkankan.com
+logging:
+    config: classpath:logback-spring.xml
+    fdkk:
+        level: INFO
+        maxHistory: 180
+    level:
+        com:
+            gis: info
+    path: /root/data/${project.name}_log
+filestorage:
+    active: aws
+    aws:
+        endpoint: http://testeurs3.4dkankan.com
+        internal-endpoint: http://testeurs3.4dkankan.com
+        access-key: AKIAWCV5QFZ3ZNELKYUY
+        access-key-secret: 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
+        bucket: test-4dkankan
+        bucket-custom-domain:
+            test-4dkankan: https://testeurs3.4dkankan.com
+server:
+    file:
+        path: /mnt/720yun_fd_manage_data/
+spring:
+    datasource:
+        driver-class-name: com.mysql.cj.jdbc.Driver
+        druid:
+            initial-size: 5
+            max-active: 20
+            max-evictable-idle-time-millis: 90000
+            max-wait: 60000
+            min-evictable-idle-time-millis: 30000
+            min-idle: 10
+            password: JK20220120%JIK
+            stat-view-servlet:
+                enabled: true
+            test-on-borrow: false
+            test-on-return: false
+            test-while-idle: true
+            time-between-eviction-runs-millis: 60000
+            url: jdbc:mysql://127.0.0.1:3306/720yun_fd_manage?serverTimezone=GMT%2B8&useUnicode=true&characterEncoding=utf8&characterSetResults=utf8&useSSL=false
+            username: root
+            validation-query: SELECT 1 FROM DUAL
+            web-stat-filter:
+                enabled: true
+        type: com.alibaba.druid.pool.DruidDataSource
+    rabbitmq:
+        host: 127.0.0.1
+        port: 5672
+        username: admin
+        password: 123456
+        virtual-host: 4dkankan
+        connection-timeout: 0
+        listener:
+            simple:
+                prefetch: 1
+                max-concurrency: 2
+                acknowledge-mode: manual #�����������ֶ�ȷ��
+        #������ϢͶ��ȷ�ϻ���
+        publisher-confirm-type: correlated
+    redis:
+        database: 0
+        host: 127.0.0.1
+        jedis:
+            pool:
+                max-active: 8
+                max-idle: 8
+                max-wait: -1ms
+                min-idle: 0
+        password: 'redis123ROOT.'
+        port: 6379
+        timeout: 3000ms
+tlog:
+    enable-invoke-time-print: true
+queue:
+    scene-queue: queue-pano-scene
+    do-slice-queue: queue-do-slice
+    relics-init-queue: relics-init-queue
+    relics-update-name-queue: relics-update-name-queue
+    pano-migrate-scene-queue: pano-migrate-scene-queue
+    pano-paystatus-scene-queue: pano-paystatus-scene-queue
+    scene-queue-work: queue-pano-scene-work-A
+config:
+    bashPath: 720yun_fd_manage/

+ 76 - 0
720yun_fd_consumer/src/main/resources/application-sitSD.yml

@@ -0,0 +1,76 @@
+domain:
+    4dkk: ${FILE_STORAGE_IP}
+logging:
+    config: classpath:logback-spring.xml
+    fdkk:
+        level: INFO
+        maxHistory: 180
+    file:
+        path: /home/backend/4dkankan_v4/qjkankan/logs/${project.name}_log
+    level:
+        com:
+            gis: info
+filestorage:
+    active: minio
+    minio:
+        endpoint: http://4dkankan-mix3d-minio:9000
+        internal-endpoint: http://4dkankan-mix3d-minio:9000
+        access-key: rohVjfYyZRJH0ovNEVWg
+        access-key-secret: ffTI2PHAzDSfV6WNElOh6S2Qdtwpux0D1nssmK9g
+        bucket: qjkankan
+        bucket-custom-domain:
+            qjkankan: http://${FILE_STORAGE_IP}
+        full-path: false
+server:
+    port: 8002
+    file:
+        path: /mnt/720yun_fd_manage_data/
+spring:
+    datasource:
+        driver-class-name: com.mysql.cj.jdbc.Driver
+        druid:
+            initial-size: 5
+            max-active: 20
+            max-evictable-idle-time-millis: 90000
+            max-wait: 60000
+            min-evictable-idle-time-millis: 30000
+            min-idle: 10
+            password: 4dkk2024cuikuan%
+            stat-view-servlet:
+                enabled: true
+            test-on-borrow: false
+            test-on-return: false
+            test-while-idle: true
+            time-between-eviction-runs-millis: 60000
+            url: jdbc:mysql://4dkankan-mix3d-mysql:3306/720yun_fd_manage?serverTimezone=GMT%2B8&useUnicode=true&characterEncoding=utf8&characterSetResults=utf8
+            username: root
+            validation-query: SELECT 1 FROM DUAL
+            web-stat-filter:
+                enabled: true
+        type: com.alibaba.druid.pool.DruidDataSource
+    rabbitmq:
+        host: 4dkankan-mix3d-rabbitmq
+        port: 5672
+        username: root
+        password: JHroot2024
+        virtual-host: 4dkankan
+        connection-timeout: 0
+        listener:
+            simple:
+                prefetch: 1
+                max-concurrency: 2
+                acknowledge-mode: manual #开启消费者手动确认
+        #开启消息投递确认机制
+        publisher-confirm-type: correlated
+tlog:
+    enable-invoke-time-print: true
+config:
+    bashPath: 720yun_fd_manage/
+queue:
+    scene-queue: queue-pano-scene
+    do-slice-queue: queue-do-slice
+    relics-init-queue: relics-init-queue
+    relics-update-name-queue: relics-update-name-queue
+    pano-migrate-scene-queue: pano-migrate-scene-queue
+    pano-paystatus-scene-queue: pano-paystatus-scene-queue
+    scene-queue-work: queue-pano-scene-work-A

+ 43 - 0
720yun_fd_consumer/src/main/resources/application.yml

@@ -0,0 +1,43 @@
+mapper:
+    identity: MYSQL
+    mappers: tk.mybatis.mapper.common.Mapper
+mybatis:
+    configuration:
+        mapUnderscoreToCamelCase: true
+pagehelper:
+    helper-dialect: mysql
+    params: count=countSql
+    reasonable: false
+    support-methods-arguments: true
+project:
+    name: 720yun_fd_consumer
+server:
+    port: 8002
+spring:
+    profiles:
+        active: locSitAws
+    resources:
+        static-locations: classpath:templates/,classpath:static/,classpath:web/
+    servlet:
+        multipart:
+            enabled: true
+            max-file-size: 500MB
+            max-request-size: 500MB
+redis:
+    token:
+        prefix: token#
+swagger:
+    # 是否开启swagger
+    enabled: true
+    # 请求前缀
+    pathMapping: /
+    production: false
+    description: ${swagger.title}
+    package: com.gis.web.controller
+    title: 全景看看-${spring.profiles.active}
+    version: 1.3.0
+knife4j:
+    # 开启增强配置
+    enable: true
+    # 开启生产环境屏蔽
+    production: false

+ 105 - 0
720yun_fd_consumer/src/main/resources/data/someData.json

@@ -0,0 +1,105 @@
+{
+  "isPassword": 0,
+  "password": "",
+  "ossSomeData": "",
+  "icon": "",
+  "description": "",
+  "updateTime": "",
+  "sceneIndex": "",
+  "catalogRoot": [
+    {
+      "id": 100,
+      "name": "一级分组",
+      "children": [
+        1
+      ]
+    }
+  ],
+  "firstScene": "",
+  "userId": "",
+  "isLogo": 1,
+  "appIcon": "",
+  "qrCode": "",
+  "createTime": "",
+  "catalogs": [
+    {
+      "id": 1,
+      "name": "默认二级分组"
+    }
+  ],
+  "isRemind": 1,
+  "name": "",
+  "pcIcon": "",
+  "scenes": [
+                    {
+                        "customMask": {
+                            "sky": {
+                                "fodderId": "",
+                                "icon": "",
+                                "scale": 1,
+                                "antidistorted": true,
+                                "isShow": false
+                            },
+                            "earth": {
+                                "fodderId": "",
+                                "icon": "",
+                                "scale": 1,
+                                "antidistorted": true,
+                                "isShow": false
+                            }
+                        },
+                        "initVisual": {
+                            "vlookat": 0,
+                            "hlookat": 0,
+                            "vlookatmin": -90,
+                            "vlookatmax": 90
+                        }
+                    }
+                ],
+  "isAuto": 1,
+  "logo": "",
+  "logoChange": false,
+  "share": "",
+  "id": "",
+  "remindTime": 1,
+  "status": 0,
+  "isShowOpeningAnimation": true,
+  "openingAnimationType": "小行星开场",
+  "backgroundMusic": {
+    "id": "",
+    "name": "",
+    "ossPath": ""
+  },
+
+  "customButton": [
+    {
+      "type": "电话",
+      "name": "电话",
+      "value": "",
+      "openMethod": "弹出层打开",
+      "isShow": false
+    },
+    {
+      "type": "链接",
+      "name": "链接",
+      "value": "",
+      "openMethod": "弹出层打开",
+      "isShow": false
+    }
+  ],
+
+
+
+  "coverPc":"",
+  "coverPcLoc":"",
+  "coverMo":"",
+  "coverSelect":"",
+
+  "explanation": {
+    "audioId": "",
+    "audioName": "",
+    "audioUrl": "",
+    "openByDefault": true,
+    "repeat": true
+  }
+}

+ 24 - 0
720yun_fd_consumer/src/main/resources/data/someDataSceneData.json

@@ -0,0 +1,24 @@
+{
+                        "customMask": {
+                            "sky": {
+                                "fodderId": "",
+                                "icon": "",
+                                "scale": 1,
+                                "antidistorted": true,
+                                "isShow": true
+                            },
+                            "earth": {
+                                "fodderId": "",
+                                "icon": "",
+                                "scale": 1,
+                                "antidistorted": true,
+                                "isShow": false
+                            }
+                        },
+                        "initVisual": {
+                            "vlookat": 0,
+                            "hlookat": 0,
+                            "vlookatmin": -90,
+                            "vlookatmax": 90
+                        }
+}

+ 78 - 0
720yun_fd_consumer/src/main/resources/data/tour.xml

@@ -0,0 +1,78 @@
+<krpano version="1.21" title="Virtual Tour">
+
+    <include url="%SWFPATH%/skin/vtourskin.xml" />
+
+    <!-- customize skin settings: maps, gyro, webvr, thumbnails, tooltips, layout, design, ... -->
+    <skin_settings maps="false"
+                   maps_type="google"
+                   maps_bing_api_key=""
+                   maps_google_api_key=""
+                   maps_zoombuttons="false"
+                   maps_loadonfirstuse="true"
+                   gyro="true"
+                   gyro_keeplookingdirection="false"
+                   webvr="true"
+                   webvr_keeplookingdirection="true"
+                   webvr_prev_next_hotspots="true"
+                   autotour="false"
+                   littleplanetintro="false"
+                   followmousecontrol="false"
+                   title="true"
+                   thumbs="true"
+                   thumbs_width="120" thumbs_height="80" thumbs_padding="10" thumbs_crop="0|40|240|160"
+                   thumbs_opened="false"
+                   thumbs_text="false"
+                   thumbs_dragging="true"
+                   thumbs_onhoverscrolling="false"
+                   thumbs_scrollbuttons="false"
+                   thumbs_scrollindicator="false"
+                   thumbs_loop="false"
+                   tooltips_buttons="false"
+                   tooltips_thumbs="false"
+                   tooltips_hotspots="false"
+                   tooltips_mapspots="false"
+                   deeplinking="false"
+                   loadscene_flags="MERGE"
+                   loadscene_blend="OPENBLEND(0.5, 0.0, 0.75, 0.05, linear)"
+                   loadscene_blend_prev="SLIDEBLEND(0.5, 180, 0.75, linear)"
+                   loadscene_blend_next="SLIDEBLEND(0.5,   0, 0.75, linear)"
+                   loadingtext="loading..."
+                   layout_width="100%"
+                   layout_maxwidth="814"
+                   controlbar_width="-24"
+                   controlbar_height="40"
+                   controlbar_offset="20"
+                   controlbar_offset_closed="-40"
+                   controlbar_overlap.no-fractionalscaling="10"
+                   controlbar_overlap.fractionalscaling="0"
+                   design_skin_images="vtourskin.png"
+                   design_bgcolor="0x2D3E50"
+                   design_bgalpha="0.8"
+                   design_bgborder="0"
+                   design_bgroundedge="1"
+                   design_bgshadow="0 4 10 0x000000 0.3"
+                   design_thumbborder_bgborder="3 0xFFFFFF 1.0"
+                   design_thumbborder_padding="2"
+                   design_thumbborder_bgroundedge="0"
+                   design_text_css="color:#FFFFFF; font-family:Arial;"
+                   design_text_shadow="1"
+    />
+
+    <!--
+        For an alternative skin design either change the <skin_settings> values
+        from above or optionally include one of the predefined designs from below.
+    -->
+    <!-- <include url="skin/vtourskin_design_flat_light.xml"  /> -->
+    <!-- <include url="skin/vtourskin_design_glass.xml"       /> -->
+    <!-- <include url="skin/vtourskin_design_ultra_light.xml" /> -->
+    <!-- <include url="skin/vtourskin_design_117.xml"         /> -->
+    <!-- <include url="skin/vtourskin_design_117round.xml"    /> -->
+    <!-- <include url="skin/vtourskin_design_black.xml"       /> -->
+    <!-- startup action - load the first scene -->
+    <action name="startup" autorun="onstart">
+        if(startscene === null OR !scene[get(startscene)], copy(startscene,scene[0].name); );
+        loadscene(get(startscene), null, MERGE);
+        if(startactions !== null, startactions() );
+    </action>
+
+</krpano>

+ 163 - 0
720yun_fd_consumer/src/main/resources/logback-spring.xml

@@ -0,0 +1,163 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<configuration>
+    <springProperty scope="context" name="LOG_MAX_HISTORY" source="logging.fdkk.maxHistory"/>
+    <!-- 日志根目录-->
+    <springProperty scope="context" name="LOG_HOME" source="logging.file.path"/>
+
+    <!-- 日志级别 -->
+    <springProperty scope="context" name="LOG_LEVEL" source="logging.fdkk.level" defaultValue="DEBUG"/>
+
+    <!--  标识这个"STDOUT" 将会添加到这个logger -->
+    <springProperty scope="context" name="STDOUT" source="log.stdout" defaultValue="STDOUT"/>
+
+    <!-- 日志文件名称-->
+    <property name="LOG_PREFIX" value="720yun"/>
+
+    <!-- 日志文件编码-->
+    <property name="LOG_CHARSET" value="UTF-8"/>
+
+    <!-- 日志文件路径+日期-->
+    <property name="LOG_DIR" value="${LOG_HOME}/%d{yyyyMMdd}"/>
+
+    <!--对日志进行格式化-->
+
+    <!--文件大小,默认10MB-->
+    <property name="MAX_FILE_SIZE" value="50MB"/>
+
+    <!-- 配置日志的滚动时间 ,表示只保留最近 10 天的日志-->
+    <property name="MAX_HISTORY" value="10"/>
+
+    <!--输出到控制台-->
+    <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
+        <encoder class="com.yomahub.tlog.core.enhance.logback.AspectLogbackEncoder">
+            <!--格式化输出:%d表示日期,%thread表示线程名,%-5level:级别从左显示5个字符宽度%msg:日志消息,%n是换行符 -->
+            <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n</pattern>
+            <charset>utf-8</charset>
+        </encoder>
+    </appender>
+    <!--输出到文件-->
+    <appender name="0" class="ch.qos.logback.core.rolling.RollingFileAppender">
+    </appender>
+
+    <!-- 定义 ALL 日志的输出方式:-->
+    <appender name="FILE_ALL" class="ch.qos.logback.core.rolling.RollingFileAppender">
+        <!--日志文件路径,日志文件名称-->
+        <File>${LOG_HOME}/${LOG_PREFIX}_all.log</File>
+        <!-- 设置滚动策略,当天的日志大小超过 ${MAX_FILE_SIZE} 文件大小时候,新的内容写入新的文件, 默认10MB -->
+        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
+            <!--日志文件路径,新的 ALL 日志文件名称,“ i ” 是个变量 -->
+            <FileNamePattern>${LOG_DIR}/${LOG_PREFIX}_all%i.log</FileNamePattern>
+
+            <!-- 配置日志的滚动时间 ,表示只保留最近 10 天的日志-->
+            <MaxHistory>${LOG_MAX_HISTORY}</MaxHistory>
+            <cleanHistoryOnStart>true</cleanHistoryOnStart>
+            <!--当天的日志大小超过 ${MAX_FILE_SIZE} 文件大小时候,新的内容写入新的文件, 默认10MB-->
+            <timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
+                <maxFileSize>${MAX_FILE_SIZE}</maxFileSize>
+            </timeBasedFileNamingAndTriggeringPolicy>
+        </rollingPolicy>
+        <encoder class="com.yomahub.tlog.core.enhance.logback.AspectLogbackEncoder">
+            <!--格式化输出:%d表示日期,%thread表示线程名,%-5level:级别从左显示5个字符宽度%msg:日志消息,%n是换行符 -->
+            <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n </pattern>
+            <charset>utf-8</charset>
+        </encoder>
+    </appender>
+
+    <!-- 定义 INFO 日志的输出方式:-->
+    <appender name="FILE_INFO" class="ch.qos.logback.core.rolling.RollingFileAppender">
+        <!-- 下面为配置只输出error级别的日志 -->
+        <filter class="ch.qos.logback.classic.filter.LevelFilter">
+            <level>INFO</level>
+            <OnMismatch>DENY</OnMismatch>
+            <OnMatch>ACCEPT</OnMatch>
+        </filter>
+        <append>true</append>
+        <!--日志文件路径,日志文件名称-->
+        <File>${LOG_HOME}/${LOG_PREFIX}_info.log</File>
+        <!-- 设置滚动策略,当天的日志大小超过 ${MAX_FILE_SIZE} 文件大小时候,新的内容写入新的文件, 默认10MB -->
+        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
+
+            <!--日志文件路径,新的 INFO 日志文件名称,“ i ” 是个变量 -->
+            <FileNamePattern>${LOG_DIR}/${LOG_PREFIX}_info%i.log</FileNamePattern>
+
+            <!-- 配置日志的滚动时间 ,表示只保留最近 10 天的日志-->
+            <MaxHistory>${LOG_MAX_HISTORY}</MaxHistory>
+            <cleanHistoryOnStart>true</cleanHistoryOnStart>
+
+            <!--当天的日志大小超过 ${MAX_FILE_SIZE} 文件大小时候,新的内容写入新的文件, 默认10MB-->
+            <timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
+                <maxFileSize>${MAX_FILE_SIZE}</maxFileSize>
+            </timeBasedFileNamingAndTriggeringPolicy>
+        </rollingPolicy>
+
+        <!-- 输出的日志内容格式化-->
+        <encoder class="com.yomahub.tlog.core.enhance.logback.AspectLogbackEncoder">
+            <!--格式化输出:%d表示日期,%thread表示线程名,%-5level:级别从左显示5个字符宽度%msg:日志消息,%n是换行符 -->
+            <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n </pattern>
+            <charset>utf-8</charset>
+        </encoder>
+    </appender>
+
+    <!-- 定义 ERROR 日志的输出方式:-->
+    <appender name="FILE_ERROR" class="ch.qos.logback.core.rolling.RollingFileAppender">
+        <!-- 下面为配置只输出error级别的日志 -->
+        <filter class="ch.qos.logback.classic.filter.LevelFilter">
+            <level>ERROR</level>
+            <OnMismatch>DENY</OnMismatch>
+            <OnMatch>ACCEPT</OnMatch>
+        </filter>
+        <!--日志文件路径,日志文件名称-->
+        <File>${LOG_HOME}/${LOG_PREFIX}_err.log</File>
+
+        <!-- 设置滚动策略,当天的日志大小超过 ${MAX_FILE_SIZE} 文件大小时候,新的内容写入新的文件, 默认10MB -->
+        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
+
+            <!--日志文件路径,新的 ERR 日志文件名称,“ i ” 是个变量 -->
+            <FileNamePattern>${LOG_DIR}/${LOG_PREFIX}_err%i.log</FileNamePattern>
+
+            <!-- 配置日志的滚动时间 ,表示只保留最近 10 天的日志-->
+            <MaxHistory>${LOG_MAX_HISTORY}</MaxHistory>
+            <cleanHistoryOnStart>true</cleanHistoryOnStart>
+
+            <!--当天的日志大小超过 ${MAX_FILE_SIZE} 文件大小时候,新的内容写入新的文件, 默认10MB-->
+            <timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
+                <maxFileSize>${MAX_FILE_SIZE}</maxFileSize>
+            </timeBasedFileNamingAndTriggeringPolicy>
+        </rollingPolicy>
+
+        <!-- 输出的日志内容格式化-->
+        <encoder class="com.yomahub.tlog.core.enhance.logback.AspectLogbackEncoder">
+            <!--格式化输出:%d表示日期,%thread表示线程名,%-5level:级别从左显示5个字符宽度%msg:日志消息,%n是换行符 -->
+            <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n</pattern>
+            <charset>utf-8</charset>
+        </encoder>
+    </appender>
+
+    <logger name="org.springframework" level="ERROR"/>
+    <logger name="org.apache.commons" level="ERROR"/>
+    <logger name="com.alibaba.dubbo.monitor" level="ERROR"/>
+    <logger name="com.alibaba.dubbo.remoting" level="ERROR"/>
+    <logger name="com.apache.ibatis" level="${LOG_LEVEL}"/>
+    <logger name="java.sql.Connection" level="${LOG_LEVEL}"/>
+    <logger name="java.sql.Statement" level="${LOG_LEVEL}"/>
+    <logger name="java.sql.PreparedStatement" level="${LOG_LEVEL}"/>
+    <logger name="io.lettuce.core.protocol" level="ERROR"/>
+    <logger name="io.lettuce.core" level="ERROR"/>
+
+    <!-- ${LOG_ROOT_LEVEL} 日志级别 -->
+    <root level="INFO">
+
+        <!-- 标识这个"${STDOUT}"将会添加到这个logger -->
+        <appender-ref ref="STDOUT"/>
+
+        <!-- FILE_ALL 日志输出添加到 logger -->
+        <appender-ref ref="FILE_ALL"/>
+
+        <!-- FILE_INFO 日志输出添加到 logger -->
+        <appender-ref ref="FILE_INFO"/>
+
+        <!-- FILE_ERROR 日志输出添加到 logger -->
+        <appender-ref ref="FILE_ERROR"/>
+    </root>
+
+</configuration>