Kaynağa Gözat

Merge branch 'release' of 4dkankan-v4/4dkankan-center-modeling-control into master

111
dengsixing 2 yıl önce
ebeveyn
işleme
74a10f85ff
22 değiştirilmiş dosya ile 811 ekleme ve 107 silme
  1. 30 0
      pom.xml
  2. 31 31
      src/main/java/com/fdkankan/contro/bean/SceneJsonBean.java
  3. 27 0
      src/main/java/com/fdkankan/contro/controller/TestController.java
  4. 105 0
      src/main/java/com/fdkankan/contro/entity/SceneAsynOperLog.java
  5. 21 4
      src/main/java/com/fdkankan/contro/entity/SceneEditInfoExt.java
  6. 97 0
      src/main/java/com/fdkankan/contro/generate/AutoGenerate.java
  7. 18 0
      src/main/java/com/fdkankan/contro/mapper/ISceneAsynOperLogMapper.java
  8. 2 0
      src/main/java/com/fdkankan/contro/mq/listener/AbstrackBuildSceneListener.java
  9. 13 4
      src/main/java/com/fdkankan/contro/mq/service/impl/BuildObjServiceImpl.java
  10. 75 6
      src/main/java/com/fdkankan/contro/mq/service/impl/BuildSceneServiceImpl.java
  11. 23 4
      src/main/java/com/fdkankan/contro/mq/service/impl/BuildV3SceneServiceImpl.java
  12. 1 1
      src/main/java/com/fdkankan/contro/schedule/ScheduleJob.java
  13. 16 0
      src/main/java/com/fdkankan/contro/service/ISceneAsynOperLogService.java
  14. 1 1
      src/main/java/com/fdkankan/contro/service/impl/FdkkV4Service.java
  15. 18 41
      src/main/java/com/fdkankan/contro/service/impl/IFdkkLaserServiceImpl.java
  16. 2 3
      src/main/java/com/fdkankan/contro/service/impl/Scene3dNumServiceImpl.java
  17. 20 0
      src/main/java/com/fdkankan/contro/service/impl/SceneAsynOperLogServiceImpl.java
  18. 59 12
      src/main/java/com/fdkankan/contro/service/impl/SceneFileBuildServiceImpl.java
  19. 4 0
      src/main/resources/bootstrap-pro.yml
  20. 4 0
      src/main/resources/bootstrap-test.yml
  21. 239 0
      src/main/resources/logback-nacos.xml
  22. 5 0
      src/main/resources/mapper/contro/SceneAsynOperLogMapper.xml

+ 30 - 0
pom.xml

@@ -158,6 +158,36 @@
       <version>3.0.0-SNAPSHOT</version>
     </dependency>
 
+    <dependency>
+      <groupId>com.yomahub</groupId>
+      <artifactId>tlog-web-spring-boot-starter</artifactId>
+      <version>1.3.6</version>
+    </dependency>
+
+    <dependency>
+      <groupId>net.logstash.logback</groupId>
+      <artifactId>logstash-logback-encoder</artifactId>
+      <version>5.0</version>
+    </dependency>
+
+    <dependency>
+      <groupId>com.yomahub</groupId>
+      <artifactId>tlog-logstash-logback</artifactId>
+      <version>1.5.0</version>
+    </dependency>
+
+    <dependency>
+      <groupId>org.apache.logging.log4j</groupId>
+      <artifactId>log4j-to-slf4j</artifactId>
+      <version>2.17.0</version>
+    </dependency>
+
+    <dependency>
+      <groupId>org.apache.logging.log4j</groupId>
+      <artifactId>log4j-api</artifactId>
+      <version>2.17.0</version>
+    </dependency>
+
   </dependencies>
   <build>
     <plugins>

+ 31 - 31
src/main/java/com/fdkankan/contro/bean/SceneJsonBean.java

@@ -1,7 +1,9 @@
 package com.fdkankan.contro.bean;
 
+import com.alibaba.fastjson.JSONObject;
 import com.baomidou.mybatisplus.annotation.TableField;
 import com.fdkankan.contro.vo.SceneEditControlsVO;
+import java.util.List;
 import lombok.AllArgsConstructor;
 import lombok.Builder;
 import lombok.Data;
@@ -75,16 +77,6 @@ public class SceneJsonBean {
      */
     private Date createTime;
 
-//    /**
-//     * 点位数量
-//     */
-//    private Integer panoCount;
-//
-//    /**
-//     * 球幕视频数量
-//     */
-//    private Integer videoCount;
-
     /**
      * 版本
      */
@@ -95,33 +87,16 @@ public class SceneJsonBean {
      */
     private Integer imgVersion;
 
-//    /**
-//     * 户型图文件路径集合
-//     */
-//    private String[] floorPlanPaths;
+    /**
+     * 场景关联版本
+     */
+    private Integer linkVersion;
 
     /**
      * 是否上传了户型图(0-否,1-是)
      */
     private Byte floorPlanUser;
 
-//    private String cadInfo;
-
-//    /**
-//     * 是否上传模型
-//     */
-//    private Byte isUploadObj;
-//
-//    /**
-//     * 重新建模的版本
-//     */
-//    private Integer floorEditVer;
-//
-//    /**
-//     * 正式发布重新建模的版本
-//     */
-//    private Integer floorPublishVer;
-
     /**
      * 初始点信息
      */
@@ -199,5 +174,30 @@ public class SceneJsonBean {
      */
     private Integer links;
 
+    /**
+     * 是否有马赛克
+     */
+    private Integer mosaic;
+
+    /**
+     * 马赛克列表
+     */
+    private List<JSONObject> mosaicList;
+
+    /**
+     * 水印文件名
+     */
+    private String waterMark;
+
+    /**
+     * 是否有滤镜(0-否,1-是)
+     */
+    private Integer filters;
+
+    /**
+     * 是否有监控摄像头数据
+     */
+    private Integer surveillances;
+
 
 }

+ 27 - 0
src/main/java/com/fdkankan/contro/controller/TestController.java

@@ -0,0 +1,27 @@
+package com.fdkankan.contro.controller;
+
+import com.fdkankan.web.response.ResultData;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+/**
+ * <p>
+ * TODO
+ * </p>
+ *
+ * @author dengsixing
+ * @since 2022/12/13
+ **/
+@RestController
+@RequestMapping("/test")
+public class TestController {
+
+    @GetMapping("/test")
+    public ResultData test(){
+        String test = null;
+        test.equals("");
+        return ResultData.ok();
+    }
+
+}

+ 105 - 0
src/main/java/com/fdkankan/contro/entity/SceneAsynOperLog.java

@@ -0,0 +1,105 @@
+package com.fdkankan.contro.entity;
+
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableLogic;
+import com.baomidou.mybatisplus.annotation.TableName;
+import java.io.Serializable;
+import java.util.Date;
+import lombok.Getter;
+import lombok.Setter;
+
+/**
+ * <p>
+ * 
+ * </p>
+ *
+ * @author 
+ * @since 2022-12-16
+ */
+@Getter
+@Setter
+@TableName("t_scene_asyn_oper_log")
+public class SceneAsynOperLog implements Serializable {
+
+    private static final long serialVersionUID = 1L;
+
+    @TableId(value = "id", type = IdType.AUTO)
+    private Long id;
+
+    /**
+     * 场景码
+     */
+    @TableField("num")
+    private String num;
+
+    /**
+     * 操作类型(upload-上传,download-下载)
+     */
+    @TableField("oper_type")
+    private String operType;
+
+    /**
+     * 模块名称
+     */
+    @TableField("module")
+    private String module;
+
+    /**
+     * 功能
+     */
+    @TableField("func")
+    private String func;
+
+    /**
+     * 版本号
+     */
+    @TableField("version")
+    private Integer version;
+
+    /**
+     * 状态(0-处理中,1-处理完成,2-处理失败)
+     */
+    @TableField("state")
+    private Integer state;
+
+    /**
+     * 下载链接
+     */
+    @TableField("url")
+    private String url;
+
+    /**
+     * 是否需要弹窗(0-否,1-是)
+     */
+    @TableField("pop")
+    private Boolean pop;
+
+    /**
+     * 扩展信息
+     */
+    @TableField("ext_data")
+    private String extData;
+
+    /**
+     * 创建时间
+     */
+    @TableField("create_time")
+    private Date createTime;
+
+    /**
+     * 修改时间
+     */
+    @TableField("update_time")
+    private Date updateTime;
+
+    /**
+     * 状态(A-有效,I-无效)
+     */
+    @TableField("rec_status")
+    @TableLogic(value = "A", delval = "I")
+    private String recStatus;
+
+
+}

+ 21 - 4
src/main/java/com/fdkankan/contro/entity/SceneEditInfoExt.java

@@ -5,7 +5,6 @@ import com.baomidou.mybatisplus.annotation.TableField;
 import com.baomidou.mybatisplus.annotation.TableId;
 import com.baomidou.mybatisplus.annotation.TableLogic;
 import com.baomidou.mybatisplus.annotation.TableName;
-import com.fdkankan.db.base.BaseEntity;
 import java.util.Date;
 import lombok.Getter;
 import lombok.Setter;
@@ -62,10 +61,10 @@ public class SceneEditInfoExt {
     private String mosaics;
 
     /**
-     * mosaics数据
+     * 水印文件名
      */
-    @TableField("share_logo_img")
-    private String shareLogoImg;
+    @TableField("water_mark")
+    private String waterMark;
 
     /**
      * 是否有场景关联(0-否,1-是)
@@ -74,6 +73,24 @@ public class SceneEditInfoExt {
     private Integer links;
 
     /**
+     * 是否有滤镜(0-否,1-是)
+     */
+    @TableField("filters")
+    private Integer filters;
+
+    /**
+     * 是否有监控摄像头(0-否,1-是)
+     */
+    @TableField("surveillances")
+    private Integer surveillances;
+
+    /**
+     * mosaics数据
+     */
+    @TableField("share_logo_img")
+    private String shareLogoImg;
+
+    /**
      * 创建时间
      */
     @TableField("create_time")

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

@@ -0,0 +1,97 @@
+package com.fdkankan.contro.generate;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.baomidou.mybatisplus.generator.FastAutoGenerator;
+import com.baomidou.mybatisplus.generator.config.OutputFile;
+import com.baomidou.mybatisplus.generator.config.rules.DateType;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+
+public class AutoGenerate {
+
+
+    public static void main(String[] args) {
+
+        String path =System.getProperty("user.dir");
+
+        generate(path,"contro", getTables(new String[]{
+                "t_scene_asyn_oper_log"
+        }));
+
+//        generate(path,"goods", getTables(new String[]{
+//                        "t_camera","t_camera_detail","t_camera_out","t_camera_space","t_camera_version",
+//                        "t_company","t_goods","t_goods_sku","t_cart","t_goods_spec",
+//                        "t_goods_spec_value","t_goods_spu_spec","t_sn_code"
+//        }));
+//
+//        generate(path,"order", getTables(new String[]{
+//                        "t_increment_order","t_invoice","t_order","t_order_item",
+//                        "t_pre_sale","t_space_sdk","t_trade_log","t_commerce_order","t_download_order","t_expansion_order"
+//        }));
+//        generate(path,"order", getTables(new String[]{
+//                        "t_virtual_order"
+//        }));
+//
+//        generate(path,"user", getTables(new String[]{
+//                        "t_user","t_user_increment","t_manager","t_province","t_increment_type","t_intercom_message","t_receiver_info"
+//        }));
+    }
+
+    public static List<String> getTables(String [] tableNames){
+        return new ArrayList<>(Arrays.asList(tableNames));
+    }
+
+
+    public static void  generate(String path,String moduleName,  List<String> tables){
+        FastAutoGenerator.create("jdbc:mysql://120.24.144.164:3306/4dkankan_v4",
+            "root","4Dage@4Dage#@168")
+                .globalConfig(builder -> {
+                    builder.author("")               //作者
+                            .outputDir(path+"\\src\\main\\java")    //输出路径(写到java目录)
+                            //.enableSwagger()           //开启swagger
+                            .commentDate("yyyy-MM-dd")
+                            .dateType(DateType.ONLY_DATE)
+                            .fileOverride();            //开启覆盖之前生成的文件
+
+                })
+                .packageConfig(builder -> {
+                    builder.parent("com.fdkankan")
+                            .moduleName(moduleName)
+                            .entity("entity")
+                            .service("service")
+                            .serviceImpl("service.impl")
+                            .controller("controller")
+                            .mapper("mapper")
+                            .xml("test.mapper")
+                            .pathInfo(Collections.singletonMap(OutputFile.mapperXml,path+"\\src\\main\\resources\\mapper\\"+moduleName));
+                })
+                .strategyConfig(builder -> {
+                    builder.addInclude(tables)
+                            .addTablePrefix("t_")
+
+                            .serviceBuilder()
+                            .formatServiceFileName("I%sService")
+                            .formatServiceImplFileName("%sServiceImpl")
+
+                            .entityBuilder()
+                            .enableLombok()
+                            .logicDeleteColumnName("rec_status")
+                            .enableTableFieldAnnotation()
+//                            .superClass(BaseEntity.class)
+
+                            .controllerBuilder()
+                            .formatFileName("%sController")
+                            .enableRestStyle()
+
+                            .mapperBuilder()
+                            .superClass(BaseMapper.class)
+                            .formatMapperFileName("I%sMapper")
+                            .enableMapperAnnotation()
+                            .formatXmlFileName("%sMapper");
+                })
+                // .templateEngine(new FreemarkerTemplateEngine()) // 使用Freemarker引擎模板,默认的是Velocity引擎模板
+                .execute();
+    }
+}

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

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

+ 2 - 0
src/main/java/com/fdkankan/contro/mq/listener/AbstrackBuildSceneListener.java

@@ -31,6 +31,7 @@ public class AbstrackBuildSceneListener implements IBuildSceneListener {
             boolean lock = redisLockUtil.lock(RedisConstants.SCENE_PREPARE_BUILDING + messageId, 24 * 3600);
             if (!lock) {
                 log.error("服务:{},消息重复消费:{}", "常驻服务", messageId);
+                channel.basicAck(message.getMessageProperties().getDeliveryTag(), false);
                 return;
             }
         }
@@ -58,6 +59,7 @@ public class AbstrackBuildSceneListener implements IBuildSceneListener {
             boolean lock = redisLockUtil.lock(RedisConstants.SCENE_POST_BUILDING + messageId, 24 * 3600);
             if (!lock) {
                 log.error("服务:{},消息重复消费:{}", "常驻服务", messageId);
+                channel.basicAck(message.getMessageProperties().getDeliveryTag(), false);
                 return;
             }
         }

+ 13 - 4
src/main/java/com/fdkankan/contro/mq/service/impl/BuildObjServiceImpl.java

@@ -3,13 +3,11 @@ package com.fdkankan.contro.mq.service.impl;
 import com.alibaba.fastjson.JSONObject;
 import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
 import com.fdkankan.common.util.FileUtils;
+import com.fdkankan.contro.entity.ScenePlus;
 import com.fdkankan.contro.entity.ScenePro;
 import com.fdkankan.contro.entity.SceneProEdit;
 import com.fdkankan.contro.mq.service.IBuildSceneService;
-import com.fdkankan.contro.service.IBuildSceneDTService;
-import com.fdkankan.contro.service.IFdkkLaserService;
-import com.fdkankan.contro.service.ISceneProEditService;
-import com.fdkankan.contro.service.ISceneProService;
+import com.fdkankan.contro.service.*;
 import com.fdkankan.contro.service.impl.FdkkV4Service;
 import com.fdkankan.fyun.face.FYunFileServiceInterface;
 import com.fdkankan.model.constants.ConstantFileName;
@@ -66,6 +64,10 @@ public class BuildObjServiceImpl implements IBuildSceneService {
     @Autowired
     private ISceneProEditService sceneProEditService;
 
+
+    @Autowired
+    private IScenePlusService scenePlusService;
+
     @Override
     public void buildScenePre(BuildSceneCallMessage message) {
         boolean success = false;
@@ -200,6 +202,13 @@ public class BuildObjServiceImpl implements IBuildSceneService {
                     .eq(SceneProEdit::getProId,scenePro.getId()));
         }
 
+        ScenePlus scenePlus = scenePlusService.getScenePlusByNum(projectNum);
+        if(!ObjectUtils.isEmpty(scenePlus)){
+            LambdaUpdateWrapper<ScenePlus> plusUpdateWrapper = new LambdaUpdateWrapper<ScenePlus>()
+                    .set(ScenePlus::getSceneStatus, -2).eq(ScenePlus::getNum, projectNum);
+            scenePlusService.update(plusUpdateWrapper);
+        }
+
         // 如果未升级V4,则升级V4
         fdkkV4Service.upgradeToV4(projectNum);
     }

+ 75 - 6
src/main/java/com/fdkankan/contro/mq/service/impl/BuildSceneServiceImpl.java

@@ -30,6 +30,7 @@ import com.fdkankan.model.constants.UploadFilePath;
 import com.fdkankan.model.enums.ModelTypeEnums;
 import com.fdkankan.model.utils.CreateHouseJsonUtil;
 import com.fdkankan.model.utils.CreateObjUtil;
+import com.fdkankan.model.utils.SceneUtil;
 import com.fdkankan.push.config.PushMessageConfig;
 import com.fdkankan.push.utils.PushMsgUtil;
 import com.fdkankan.rabbitmq.bean.BuildSceneCallMessage;
@@ -112,6 +113,8 @@ public class BuildSceneServiceImpl implements IBuildSceneService {
 
     @Autowired
     private ICompanyService companyService;
+    @Autowired
+    private ISceneAsynOperLogService sceneAsynOperLogService;
 
     @Override
     public void buildScenePre(BuildSceneCallMessage message) {
@@ -126,10 +129,26 @@ public class BuildSceneServiceImpl implements IBuildSceneService {
             //下载资源到本地
             this.downLoadSource(message, message.getPath());
 
+            JSONObject fdageJson = JSONObject.parseObject(FileUtils.readFile(message.getPath().concat("/capture/data.fdage")));
+
+            boolean rewrite = false;
+            // 兼容旧的数据,防止OnlyExportMeshObj标志未删除掉
+            if (fdageJson.containsKey("OnlyExportMeshObj")) {
+                log.info("data.fdage 包含 OnlyExportMeshObj,进行去除!");
+                // 写入data.fdage 防止重算
+                fdageJson.remove("OnlyExportMeshObj");
+                String ossPath = getOssPath(message.getPath());
+                fYunFileService.uploadFile(fdageJson.toJSONString().getBytes(), ossPath + "data.fdage");
+                rewrite = true;
+            }
+
             if (!ObjectUtils.isEmpty(modelType)) {
                 // 修改dataFdage文件
-                JSONObject fdageJson = JSONObject.parseObject(FileUtils.readFile(message.getPath().concat("/capture/data.fdage")));
                 fdageJson.put("modelType", modelType);
+                rewrite = true;
+            }
+
+            if (rewrite) {
                 FileUtils.writeFile(message.getPath().concat("/capture/data.fdage"), fdageJson.toJSONString());
             }
 
@@ -159,14 +178,19 @@ public class BuildSceneServiceImpl implements IBuildSceneService {
         }
     }
 
-    @Override
-    public void downLoadSource(BuildSceneCallMessage buildSceneMqMessage,String path){
+    private String getOssPath(String path) {
         String ossPath = ConstantFilePath.OSS_PREFIX
                 + path.replace(ConstantFilePath.BUILD_MODEL_PATH, "")
                 .replace(ConstantFilePath.BUILD_MODEL_LASER_PATH, "");
         if (!ossPath.endsWith("/")) {
             ossPath = ossPath.concat("/");
         }
+        return ossPath;
+    }
+
+    @Override
+    public void downLoadSource(BuildSceneCallMessage buildSceneMqMessage,String path){
+        String ossPath = getOssPath(path);
         fYunFileService.downloadFileByCommand(path + File.separator + "capture", ossPath);
     }
 
@@ -257,10 +281,16 @@ public class BuildSceneServiceImpl implements IBuildSceneService {
             //拷贝部分文件到编辑目录,用于用户编辑
             this.copyToEditDir(sceneCode);
 
+            //计算完毕后,同步全景图到缓存目录
+            this.cachePanorama(path, sceneCode);
+
             //生成houseTypejson并上传
             uploadFiles.entrySet().stream().filter(entry-> FileNameUtil.getName(entry.getKey()).equals("floorplan_cad.json"))
                     .forEach(entry-> uploadHouseTypeJson(sceneCode,entry.getKey()));
 
+            //重置异步操作记录
+            this.removeSceneAsynOperLog(sceneCode);
+
             //写scene.json
 
 
@@ -296,11 +326,49 @@ public class BuildSceneServiceImpl implements IBuildSceneService {
             log.info("场景计算结果处理结束,场景码:{}", sceneCode);
 
         }catch (Exception e){
-            e.printStackTrace();
+            log.error("场景计算结果处理出错!", e);
             buildSceneDTService.handBaseFail("场景计算结果处理出错!", message.getPath(), sceneCode, "计算控制服务器");
         }
     }
 
+    private void removeSceneAsynOperLog(String num){
+        List<SceneAsynOperLog> list = sceneAsynOperLogService.list(new LambdaQueryWrapper<SceneAsynOperLog>().eq(SceneAsynOperLog::getNum, num));
+        if(CollUtil.isEmpty(list)){
+            return;
+        }
+        //删除数据库记录
+        List<Long> deleteIdList = list.parallelStream().map(item -> item.getId()).collect(Collectors.toList());
+        sceneAsynOperLogService.removeByIds(deleteIdList);
+
+        list.parallelStream().forEach(item -> {
+            if(StrUtil.isNotEmpty(item.getUrl())){
+                try {
+                    fYunFileService.deleteFile(item.getUrl());
+                } catch (IOException e) {
+                    log.warn("删除oss全景图下载压缩包失败,key:{}", item.getUrl());
+                }
+            }
+        });
+    }
+
+    private void cachePanorama(String dataSource, String num){
+        String cachedImagesPath = String.format(ConstantFilePath.SCENE_CACHE_IMAGES, num);
+        //将全景图缓存到缓存目录
+        List<String> imagesList = FileUtil.listFileNames(dataSource + "/caches/images");
+        //先清除旧的全景图
+        cn.hutool.core.io.FileUtil.del(cachedImagesPath);
+        String visionPath = dataSource + "/results/vision.txt";
+        List<String> panoramaImageList = SceneUtil.getPanoramaImageList(visionPath);
+        imagesList.stream().forEach(fileName -> {
+            if (panoramaImageList.contains(fileName)) {
+                String srcPath = dataSource + "/caches/images/" + fileName;
+                String targetPath = cachedImagesPath + fileName;
+                log.info("源文件:{}, 目标文件:{}", srcPath, targetPath);
+                cn.hutool.core.io.FileUtil.copy(srcPath, targetPath, true);
+            }
+        });
+    }
+
     private Map<String, String> getUploadFiles(ScenePlus scenePlus,String path,Integer cameraType,JSONObject fdageData) throws Exception {
         if (ObjectUtils.isEmpty(scenePlus)) {
             throw new Exception("未找到场景信息:" + path);
@@ -384,8 +452,9 @@ public class BuildSceneServiceImpl implements IBuildSceneService {
         map.put(resultsPath + "vision.modeldata", imagesPath + "vision.modeldata");
 
         log.info("数据转换完成:" + projectNum);
-
-        FileUtil.touch("/mnt/4Dkankan/scene/data" + File.separator + "data" + projectNum);
+        if(!new File("/mnt/4Dkankan/scene/data" + File.separator + "data" + projectNum).exists()){
+            FileUtil.mkdir("/mnt/4Dkankan/scene/data" + File.separator + "data" + projectNum);
+        }
         map.put(resultsPath + "floorplan.json", dataViewPath + "floor.json");
         map.put(resultsPath + "floorplan_cad.json", dataViewPath + "floorplan_cad.json");
         map.put(path + File.separator + "capture/stitch_params.txt", dataViewPath + "stitch_params.txt");

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

@@ -105,11 +105,25 @@ public class BuildV3SceneServiceImpl implements IBuildSceneService {
             //根据相机类型,组装资源路径
             //下载资源到本地
             this.downLoadSource(message, message.getPath());
+            JSONObject fdageJson = JSONObject.parseObject(FileUtils.readFile(message.getPath().concat("/capture/data.fdage")));
+            // 兼容旧的数据,防止OnlyExportMeshObj标志未删除掉
+            boolean rewrite = false;
+            if (fdageJson.containsKey("OnlyExportMeshObj")) {
+                log.info("data.fdage 包含 OnlyExportMeshObj,进行去除!");
+                // 写入data.fdage 防止重算
+                fdageJson.remove("OnlyExportMeshObj");
+                String ossPath = getOssPath(message.getPath());
+                fYunFileService.uploadFile(fdageJson.toJSONString().getBytes(), ossPath + "data.fdage");
+                rewrite = true;
+            }
 
             if (!ObjectUtils.isEmpty(modelSceneKind)) {
                 // 修改dataFdage文件
-                JSONObject fdageJson = JSONObject.parseObject(FileUtils.readFile(message.getPath().concat("/capture/data.fdage")));
                 fdageJson.put("modelType", modelSceneKind);
+                rewrite = true;
+            }
+
+            if (rewrite) {
                 FileUtils.writeFile(message.getPath().concat("/capture/data.fdage"), fdageJson.toJSONString());
             }
 
@@ -135,14 +149,19 @@ public class BuildV3SceneServiceImpl implements IBuildSceneService {
         }
     }
 
-    @Override
-    public void downLoadSource(BuildSceneCallMessage buildSceneMqMessage,String path){
+    private String getOssPath(String path) {
         String ossPath = ConstantFilePath.OSS_PREFIX
                 + path.replace(ConstantFilePath.BUILD_MODEL_PATH, "")
                 .replace(ConstantFilePath.BUILD_MODEL_LASER_PATH, "");
         if (!ossPath.endsWith("/")) {
             ossPath = ossPath.concat("/");
         }
+        return ossPath;
+    }
+
+    @Override
+    public void downLoadSource(BuildSceneCallMessage buildSceneMqMessage,String path){
+        String ossPath = getOssPath(path);
         fYunFileService.downloadFileByCommand(path + File.separator + "capture", ossPath);
     }
 
@@ -255,7 +274,7 @@ public class BuildV3SceneServiceImpl implements IBuildSceneService {
             }
 
         }catch (Exception e){
-            e.printStackTrace();
+            log.error("场景计算结果处理出错!", e);
             buildSceneDTService.handBaseFail("场景计算结果处理出错!", message.getPath(), sceneCode, "计算控制服务器");
         }
     }

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

@@ -36,7 +36,7 @@ public class ScheduleJob {
                 log.info(scalingService.createEcs());
             }
         } catch (Exception e) {
-            e.printStackTrace();
+            log.error("弹性升缩开启失败!", e);
             log.error(e.getMessage());
         }
     }

+ 16 - 0
src/main/java/com/fdkankan/contro/service/ISceneAsynOperLogService.java

@@ -0,0 +1,16 @@
+package com.fdkankan.contro.service;
+
+import com.fdkankan.contro.entity.SceneAsynOperLog;
+import com.baomidou.mybatisplus.extension.service.IService;
+
+/**
+ * <p>
+ *  服务类
+ * </p>
+ *
+ * @author 
+ * @since 2022-12-16
+ */
+public interface ISceneAsynOperLogService extends IService<SceneAsynOperLog> {
+
+}

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

@@ -64,7 +64,7 @@ public class FdkkV4Service {
 
         //修改场景状态为升级中
         LambdaUpdateWrapper<ScenePro> wrapper = new LambdaUpdateWrapper<>();
-        wrapper.set(ScenePro::getStatus,0).set(ScenePro::getIsUpgrade,2).eq(ScenePro::getNum,num);
+        wrapper.set(ScenePro::getIsUpgrade,2).eq(ScenePro::getNum,num);
         sceneProService.update(wrapper);
     }
 

+ 18 - 41
src/main/java/com/fdkankan/contro/service/impl/IFdkkLaserServiceImpl.java

@@ -9,15 +9,12 @@ import com.fdkankan.contro.entity.ScenePro;
 import com.fdkankan.contro.service.IFdkkLaserService;
 import com.fdkankan.contro.service.IScenePlusService;
 import com.fdkankan.contro.service.ISceneProService;
-import com.fdkankan.web.response.Result;
+import com.fdkankan.rabbitmq.util.RabbitMqProducer;
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.beans.factory.annotation.Value;
-import org.springframework.http.HttpStatus;
-import org.springframework.http.ResponseEntity;
 import org.springframework.stereotype.Service;
 import org.springframework.util.ObjectUtils;
-import org.springframework.web.client.RestTemplate;
 
 import java.io.File;
 import java.util.Date;
@@ -28,23 +25,23 @@ import java.util.Map;
 @Slf4j
 public class IFdkkLaserServiceImpl implements IFdkkLaserService {
 
-    private final String SAVE_SCENE_URL_TEMPLATE = "/laser/init/%s/saveOrEdit";
-    private final String EDIT_LASER_BUILD_STATUS_URL = "/laser/4dage/scene/editBuildStatus";
-    private final String ENABLE_COOPERATION_CAMERA_URL = "/laser/4dage/scene/cooperation/cameraSave";
-
-    @Value("${4dkk.laserService.host}")
-    private String laserHost;
-
-    private RestTemplate restTemplate = new RestTemplate();
-
     @Autowired
     private ISceneProService sceneProService;
 
     @Autowired
     private IScenePlusService scenePlusService;
 
+    @Autowired
+    private RabbitMqProducer rabbitMqProducer;
+
+    @Value("${queue.application.laser.update-scene}")
+    private String updateScene;
+
+    @Value("${queue.application.laser.update-build-status}")
+    private String updateBuildStatus;
+
+
     public void updateSceneStatus(String sceneCode, int sceneStatus, String path, Date createTime) {
-        String url = laserHost + String.format(SAVE_SCENE_URL_TEMPLATE, sceneCode);
         Map<String, Object> params = new HashMap<>();
         params.put("sceneCode", sceneCode);
         params.put("status", sceneStatus);
@@ -53,12 +50,7 @@ public class IFdkkLaserServiceImpl implements IFdkkLaserService {
         if (!ObjectUtils.isEmpty(path)) {
             params.put("path", path);
         }
-        log.info("自研激光转台相机同步,url:{},params:{}", url, JSONObject.toJSONString(params));
-        ResponseEntity<Result> responseEntity = restTemplate.postForEntity(url, params, Result.class);
-        log.info("自研激光转台相机同步,url:{},params:{},结果:{}", url, JSONObject.toJSONString(params), JSONObject.toJSONString(responseEntity.getBody()));
-        if (responseEntity.getStatusCode() != HttpStatus.OK || responseEntity.getBody().getCode() != HttpStatus.OK.value()) {
-            log.error("激光场景状态同步失败!");
-        }
+        rabbitMqProducer.sendByWorkQueue(updateScene, params);
     }
 
     public void syncBuildResult(String sceneNum, String dataSource,Date createTime) {
@@ -97,21 +89,14 @@ public class IFdkkLaserServiceImpl implements IFdkkLaserService {
 
     @Override
     public void pushBuildStatusToLaserSystem(String projectNum, String laserObjFilePath) {
-        String url = laserHost + EDIT_LASER_BUILD_STATUS_URL;
         Map<String, String> params = new HashMap<>();
         params.put("sceneCode", projectNum);
         params.put("objPath", laserObjFilePath);
-        log.info("激光系统同步BuildStatus,url:{},params:{}", ENABLE_COOPERATION_CAMERA_URL, JSONObject.toJSONString(params));
-        ResponseEntity<com.fdkankan.contro.common.Result> responseEntity = restTemplate.postForEntity(url, params, com.fdkankan.contro.common.Result.class);
-        log.info("激光系统同步BuildStatus,url:{},params:{},结果:{}", url, JSONObject.toJSONString(params), JSONObject.toJSONString(responseEntity.getBody()));
-        if (responseEntity.getStatusCode() != HttpStatus.OK || responseEntity.getBody().getCode() != HttpStatus.OK.value()) {
-            log.error("激光系统同步BuildStatus");
-        }
+        rabbitMqProducer.sendByWorkQueue(updateBuildStatus, params);
     }
 
 
     public void saveScene(ScenePlus scenePlus, String scenePassword, Camera cameraEntity, String phone, boolean rebuild) {
-        String url = laserHost + String.format(SAVE_SCENE_URL_TEMPLATE, scenePlus.getNum());
         Map<String, Object> params = new HashMap<>();
         params.put("childName", cameraEntity.getChildName());
         params.put("createTime", DateUtil.date2String(scenePlus.getCreateTime(), null));
@@ -127,18 +112,15 @@ public class IFdkkLaserServiceImpl implements IFdkkLaserService {
         params.put("version",getSceneVersion(scenePlus.getNum()));
         params.put("title", scenePlus.getTitle());
         params.put("userId", scenePlus.getUserId());
-        log.info("自研激光转台相机同步,url:{},params:{}", url, JSONObject.toJSONString(params));
-        ResponseEntity<Result> responseEntity = restTemplate.postForEntity(url, params, Result.class);
-        log.info("自研激光转台相机同步,url:{},params:{},结果,{}", url, JSONObject.toJSONString(params), JSONObject.toJSONString(responseEntity.getBody()));
-        if (responseEntity.getStatusCode() != HttpStatus.OK || responseEntity.getBody().getCode() != HttpStatus.OK.value()) {
-            log.error("激光场景状态同步失败!");
-        }
+        rabbitMqProducer.sendByWorkQueue(updateScene, params);
     }
 
     public void saveScene(ScenePro scenePro, String scenePassword, Camera cameraEntity, String phone, boolean rebuild) {
-        String url = laserHost + String.format(SAVE_SCENE_URL_TEMPLATE, scenePro.getNum());
         Map<String, Object> params = new HashMap<>();
         params.put("childName", cameraEntity.getChildName());
+        if(ObjectUtils.isEmpty(scenePro.getCreateTime())){
+            scenePro.setCreateTime(new Date());
+        }
         params.put("createTime", DateUtil.date2String(scenePro.getCreateTime(), null));
         params.put("phone", phone);
         params.put("sceneCode", scenePro.getNum());
@@ -152,12 +134,7 @@ public class IFdkkLaserServiceImpl implements IFdkkLaserService {
         params.put("version",getSceneVersion(scenePro.getNum()));
         params.put("title", scenePro.getSceneName());
         params.put("userId", scenePro.getUserId());
-        log.info("自研激光转台相机同步,url:{},params:{}", url, JSONObject.toJSONString(params));
-        ResponseEntity<Result> responseEntity = restTemplate.postForEntity(url, params, Result.class);
-        log.info("自研激光转台相机同步,url:{},params:{},结果,{}", url, JSONObject.toJSONString(params), JSONObject.toJSONString(responseEntity.getBody()));
-        if (responseEntity.getStatusCode() != HttpStatus.OK || responseEntity.getBody().getCode() != HttpStatus.OK.value()) {
-            log.error("激光场景状态同步失败!");
-        }
+        rabbitMqProducer.sendByWorkQueue(updateScene, params);
     }
 
     private String getSceneVersion(String num) {

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

@@ -86,7 +86,7 @@ public class Scene3dNumServiceImpl extends ServiceImpl<IScene3dNumMapper, Scene3
             try {
                 Thread.sleep(2000);
             } catch (InterruptedException e) {
-                e.printStackTrace();
+                log.error("场景码加载缓存失败", e);
             }
         }
         sceneNum = redisUtil.lLeftPop(RedisKey.FDKANKAN_SCENE_NUMS);
@@ -129,8 +129,7 @@ public class Scene3dNumServiceImpl extends ServiceImpl<IScene3dNumMapper, Scene3
                 try{
                     this.saveBatch(scene3dNumList);
                 }catch (Exception e){
-                    log.error("场景码插入异常!");
-                    e.printStackTrace();
+                    log.error("场景码插入异常!",e);
                 }
             }
         }finally {

+ 20 - 0
src/main/java/com/fdkankan/contro/service/impl/SceneAsynOperLogServiceImpl.java

@@ -0,0 +1,20 @@
+package com.fdkankan.contro.service.impl;
+
+import com.fdkankan.contro.entity.SceneAsynOperLog;
+import com.fdkankan.contro.mapper.ISceneAsynOperLogMapper;
+import com.fdkankan.contro.service.ISceneAsynOperLogService;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import org.springframework.stereotype.Service;
+
+/**
+ * <p>
+ *  服务实现类
+ * </p>
+ *
+ * @author 
+ * @since 2022-12-16
+ */
+@Service
+public class SceneAsynOperLogServiceImpl extends ServiceImpl<ISceneAsynOperLogMapper, SceneAsynOperLog> implements ISceneAsynOperLogService {
+
+}

+ 59 - 12
src/main/java/com/fdkankan/contro/service/impl/SceneFileBuildServiceImpl.java

@@ -42,6 +42,7 @@ import org.apache.commons.lang3.StringUtils;
 import org.joda.time.DateTime;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.beans.factory.annotation.Value;
+import org.springframework.cloud.context.config.annotation.RefreshScope;
 import org.springframework.http.*;
 import org.springframework.stereotype.Service;
 import org.springframework.util.LinkedMultiValueMap;
@@ -62,6 +63,7 @@ import java.util.*;
  * @author dengsixing
  * @since 2021-12-23
  */
+@RefreshScope
 @Slf4j
 @Service
 public class SceneFileBuildServiceImpl extends ServiceImpl<ISceneFileBuildMapper, SceneFileBuild> implements ISceneFileBuildService {
@@ -83,6 +85,9 @@ public class SceneFileBuildServiceImpl extends ServiceImpl<ISceneFileBuildMapper
     @Value("${v3.controlUrl:#{null}}")
     private String v3controlUrl;
 
+    @Value("${build.notSupport.beforeTime:202203}")
+    private String jgNotSupportBuildTime;
+
     @Autowired
     private RedisUtil redisUtil;
 
@@ -385,7 +390,7 @@ public class SceneFileBuildServiceImpl extends ServiceImpl<ISceneFileBuildMapper
                 mqMessage.setFlexibility(-1);
             }
         }
-
+        mqMessage.getExt().put("deleteExtras", true);
         rabbitMqProducer.sendByWorkQueue(queueModelingPre, mqMessage);
 
         return scenePlusVO;
@@ -703,6 +708,10 @@ public class SceneFileBuildServiceImpl extends ServiceImpl<ISceneFileBuildMapper
         // 判断是否是V3的场景
         ScenePro scenePro = sceneProService.getOne(
                 new LambdaQueryWrapper<ScenePro>().like(ScenePro::getDataSource, fileId));
+
+        //激光场景校验是否能够计算
+        this.checkJgCanBuild(scenePro);
+
         if (ObjectUtils.isEmpty(scenePro) || (!ObjectUtils.isEmpty(scenePro.getIsUpgrade()) && scenePro.getIsUpgrade() == 1)) {
             scenePlusVO = buildScene(fileId, prefixBuffer.toString(), fdageJson, buildType, cameraType);
         } else {
@@ -869,13 +878,6 @@ public class SceneFileBuildServiceImpl extends ServiceImpl<ISceneFileBuildMapper
 
             SceneEditInfo oldSceneEditInfo = sceneEditInfoService.getByScenePlusId(oldScene.getId());
             SceneEditInfoExt oldSceneEditeIinfoExt = sceneEditInfoExtService.getByEditInfoId(oldSceneEditInfo.getId());
-            if(StrUtil.isNotBlank(sceneKey)) {
-                sceneEditInfo.setScenePassword(sceneKey);
-                sceneEditControls.setShowLock((int) CommonStatus.YES.code());
-            }else{
-                sceneEditInfo.setScenePassword("");
-                sceneEditControls.setShowLock((int)CommonStatus.NO.code());
-            }
             sceneEditInfo.setTitle(scenePlus.getTitle());
             sceneEditInfo.setDescription(scenePlus.getDescription());
             sceneEditInfo.setId(oldSceneEditInfo.getId());
@@ -1063,6 +1065,10 @@ public class SceneFileBuildServiceImpl extends ServiceImpl<ISceneFileBuildMapper
     public ResultData rebuildScene(String num,Boolean force,Boolean deleteExtras) throws IOException {
 
         ScenePro scenePro = sceneProService.getByNum(num);
+
+        //激光场景校验是否能够计算
+        this.checkJgCanBuild(scenePro);
+
         //如果是v3场景,不允许重算,需要升级v4后再调此接口进行重算
         if(Objects.nonNull(scenePro) && (Objects.isNull(scenePro.getIsUpgrade())
             || scenePro.getIsUpgrade() != CommonStatus.YES.code().intValue())){
@@ -1141,6 +1147,39 @@ public class SceneFileBuildServiceImpl extends ServiceImpl<ISceneFileBuildMapper
         return ResultData.ok();
     }
 
+    /**
+     * 由于算法不支持2022年三月份前的激光场景计算,这里需要校验是否是能计算,不能就退出重算
+     * @return
+     */
+    private void checkJgCanBuild(ScenePro scenePro){
+
+        if(Objects.isNull(scenePro) || StrUtil.isEmpty(scenePro.getDataSource()) || !SceneSource.JG.code().equals(scenePro.getSceneSource())){
+            return;
+        }
+        cn.hutool.core.date.DateTime limitTime = DateExtUtil.parse(jgNotSupportBuildTime, DateExtUtil.dateStyle10);
+        String dataSource = scenePro.getDataSource();
+        String sceneDateTimeStr = dataSource.substring(dataSource.lastIndexOf("_") + 1).substring(0, 6);
+        //如果截取的时间串是空的,无法判断时间,就退出,正常走计算逻辑
+        if(StrUtil.isEmpty(sceneDateTimeStr)){
+            return;
+        }
+        cn.hutool.core.date.DateTime sceneDateTime = null;
+        try{
+            sceneDateTime = DateExtUtil.parse(sceneDateTimeStr, DateExtUtil.dateStyle10);
+            if(Objects.isNull(sceneDateTime)){
+                return;
+            }
+        }catch (Exception e){
+            //如果截取的时间串转换日期错误,无法判断时间,退出函数
+            return;
+        }
+
+        if(sceneDateTime.before(limitTime)){
+            throw new BusinessException(ErrorCode.FAILURE_CODE_5067);
+        }
+
+    }
+
     public ResultData rebuildV3Scene(ScenePro scenePro,String num,Boolean force) throws IOException {
 
 
@@ -1226,13 +1265,11 @@ public class SceneFileBuildServiceImpl extends ServiceImpl<ISceneFileBuildMapper
         String cameraName = fdageData.getJSONObject("cam").getString("uuid");
         Camera cameraEntity = cameraService.getByChildName(cameraName);
         if(cameraEntity ==  null){
-            log.error("该相机不存在:" + cameraName);
             throw new BusinessException(ErrorCode.FAILURE_CODE_6003);
         }
 
         CameraDetail detailEntity = cameraDetailService.getByCameraId(cameraEntity.getId());
         if(detailEntity ==  null){
-            log.error("该相机详情不存在:" + cameraName);
             throw new BusinessException(ErrorCode.FAILURE_CODE_6003);
         }
 
@@ -1282,7 +1319,16 @@ public class SceneFileBuildServiceImpl extends ServiceImpl<ISceneFileBuildMapper
                     icon = fYunFileConfig.getHost() + imgViewPath + fdageData.getString("icon");
                     log.info("上传icon成功....");
                 }
-                buildScenePost(dataSource,fdageData,"V3",cameraType,sceneNum,detailEntity,0,icon);
+                buildScenePost(dataSource, fdageData, "V3", cameraType, sceneNum, detailEntity, 0, icon);
+                if (cameraType == 14) {
+                    // 通知激光系统
+                    ScenePlus scenePlus = scenePlusService.getScenePlusByNum(sceneNum);
+                    String userName = null;
+                    if (!ObjectUtils.isEmpty(detailEntity.getUserId())) {
+                        userName = userService.getSSOUserByUserId(detailEntity.getUserId()).getUserName();
+                    }
+                    fdkkLaserService.saveScene(scenePlus, fdageData.getString("pwd"), cameraEntity, userName, false);
+                }
                 break;
         }
         Map<String,Object> result = new HashMap<>();
@@ -1328,7 +1374,8 @@ public class SceneFileBuildServiceImpl extends ServiceImpl<ISceneFileBuildMapper
 
         // 通知激光场景系统开始构建场景
         if(cameraType == 14){
-            fdkkLaserService.saveScene(scenePro, null, cameraEntity, userName, true);
+            scenePro.setStatus(0);
+            fdkkLaserService.saveScene(scenePro, jsonObject.getString("pwd"), cameraEntity, userName, false);
         }
 
         BuildSceneCallMessage buildSceneMqMessage = this.getBuildSceneMqMessage(

+ 4 - 0
src/main/resources/bootstrap-pro.yml

@@ -33,6 +33,10 @@ spring:
           - data-id: common-scaling.yaml
             group: DEFAULT_GROUP
             refresh: true
+
+          - data-id: common-logback-config.yaml
+            group: DEFAULT_GROUP
+            refresh: true
       discovery:
         server-addr: ${spring.cloud.nacos.config.server-addr}
         namespace: ${spring.cloud.nacos.config.namespace}

+ 4 - 0
src/main/resources/bootstrap-test.yml

@@ -33,6 +33,10 @@ spring:
           - data-id: common-scaling.yaml
             group: DEFAULT_GROUP
             refresh: true
+
+          - data-id: common-logback-config.yaml
+            group: DEFAULT_GROUP
+            refresh: true
       discovery:
         server-addr: ${spring.cloud.nacos.config.server-addr}
         namespace: ${spring.cloud.nacos.config.namespace}

+ 239 - 0
src/main/resources/logback-nacos.xml

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

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

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