Ver código fonte

Merge remote-tracking branch 'origin/hotfix-拷贝场景重新补拍' into feature-v4.5.0-20221202

# Conflicts:
#	src/main/java/com/fdkankan/contro/mq/service/impl/BuildObjServiceImpl.java
#	src/main/java/com/fdkankan/contro/mq/service/impl/BuildSceneServiceImpl.java
dengsixing 2 anos atrás
pai
commit
3b8ab2c5e9

+ 2 - 0
src/main/java/com/fdkankan/contro/constant/RedisConstants.java

@@ -4,4 +4,6 @@ public class RedisConstants {
     public static final String FOLDER_FILEID_BUILD = "model-controls:folder:%s";
     public static final String FILEID_FOLDER_BUILD = "model-controls:fileId:%s";
     public static final String FOLDER_LOCK_BUILD = "model-controls:lock:%s";
+    public static final String SCENE_PREPARE_BUILDING = "model-controls:scene:building:prepare:message:";
+    public static final String SCENE_POST_BUILDING = "model-controls:scene:building:post:message:";
 }

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

@@ -1,12 +1,15 @@
 package com.fdkankan.contro.mq.listener;
 
 import com.alibaba.fastjson.JSONObject;
+import com.fdkankan.contro.constant.RedisConstants;
 import com.fdkankan.contro.mq.service.IBuildSceneService;
 import com.fdkankan.rabbitmq.bean.BuildSceneCallMessage;
 import com.fdkankan.rabbitmq.bean.BuildSceneResultMqMessage;
+import com.fdkankan.redis.util.RedisLockUtil;
 import com.rabbitmq.client.Channel;
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.amqp.core.Message;
+import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.util.ObjectUtils;
 
 import java.io.IOException;
@@ -15,9 +18,23 @@ import java.util.HashMap;
 
 @Slf4j
 public class AbstrackBuildSceneListener implements IBuildSceneListener {
+
+    @Autowired
+    private RedisLockUtil redisLockUtil;
+
     @Override
     public void preHandle(Channel channel, String queueName, Message message, IBuildSceneService buildSceneService) throws IOException {
+        // 添加消息幂等处理
         String messageId = message.getMessageProperties().getMessageId();
+        if(!ObjectUtils.isEmpty(messageId)){
+            // 设置消息id幂等性,防止消息重复消费
+            boolean lock = redisLockUtil.lock(RedisConstants.SCENE_PREPARE_BUILDING + messageId, 24 * 3600);
+            if (!lock) {
+                log.error("服务:{},消息重复消费:{}", "常驻服务", messageId);
+                return;
+            }
+        }
+
         String msg = new String(message.getBody(), StandardCharsets.UTF_8);
         log.info("开始准备场景计算资源,队列名:{},id:{},消息体:{}", queueName, messageId, msg);
         BuildSceneCallMessage buildSceneMessage = JSONObject.parseObject(msg, BuildSceneCallMessage.class);
@@ -34,7 +51,17 @@ public class AbstrackBuildSceneListener implements IBuildSceneListener {
 
     @Override
     public void postHandle(Channel channel, String queueName, Message message, IBuildSceneService buildSceneService) throws Exception {
+        // 添加消息幂等处理
         String messageId = message.getMessageProperties().getMessageId();
+        if(!ObjectUtils.isEmpty(messageId)){
+            // 设置消息id幂等性,防止消息重复消费
+            boolean lock = redisLockUtil.lock(RedisConstants.SCENE_POST_BUILDING + messageId, 24 * 3600);
+            if (!lock) {
+                log.error("服务:{},消息重复消费:{}", "常驻服务", messageId);
+                return;
+            }
+        }
+
         String msg = new String(message.getBody(), StandardCharsets.UTF_8);
         log.info("场景计算完成,开始处理场景计算结果,队列名:{},id:{},消息体:{}", queueName, messageId, msg);
         BuildSceneResultMqMessage buildSceneMessage = JSONObject.parseObject(msg, BuildSceneResultMqMessage.class);

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

@@ -6,10 +6,13 @@ import com.alibaba.fastjson.JSONObject;
 import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
 import com.fdkankan.common.constant.ModelKind;
 import com.fdkankan.common.util.FileUtils;
-import com.fdkankan.contro.bean.SceneJsonBean;
-import com.fdkankan.contro.entity.*;
+import com.fdkankan.contro.entity.ScenePro;
+import com.fdkankan.contro.entity.SceneProEdit;
 import com.fdkankan.contro.mq.service.IBuildSceneService;
-import com.fdkankan.contro.service.*;
+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.impl.FdkkV4Service;
 import com.fdkankan.fyun.face.FYunFileServiceInterface;
 import com.fdkankan.model.constants.ConstantFileName;
@@ -85,9 +88,6 @@ public class BuildObjServiceImpl implements IBuildSceneService {
     @Autowired
     private ISceneProEditService sceneProEditService;
 
-    @Autowired
-    private RedisUtil redisUtil;
-
     @Override
     public void buildScenePre(BuildSceneCallMessage message) {
         boolean success = false;

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

@@ -239,14 +239,17 @@ public class BuildSceneServiceImpl implements IBuildSceneService {
             //上传文件
             fYunFileService.uploadMulFiles(uploadFiles);
 
+            Map<String,String> damFileHeaders = new HashMap<>();
+            damFileHeaders.put("Content-Encoding","gzip");
             if(modelKind.equals(ModelKind.DAM.code())){
-                Map<String,String> damFileHeaders = new HashMap<>();
-                damFileHeaders.put("Content-Encoding","gzip");
                 if (!fYunFileService.getFyunType().equals(FYunTypeEnum.LOCAL.code())) {
                     // dam 文件设置请求头
                     uploadFiles.entrySet().stream().filter(entry -> FileNameUtil.extName(entry.getKey()).equals("dam"))
-                        .filter(entry -> new File(entry.getKey()).exists())
                         .forEach(entry -> {
+                            if (!new File(entry.getKey()).exists()) {
+                                log.error("文件不存在,不予gzip压缩,文件路径:{}", entry.getKey());
+                                return;
+                            }
                             // gzip压缩
                             FileUtil.writeBytes(ZipUtil.gzip(new File(entry.getKey())), entry.getKey() + ".gzip");
                             // 重命名

+ 30 - 6
src/main/java/com/fdkankan/contro/service/impl/SceneFileBuildServiceImpl.java

@@ -31,6 +31,7 @@ import com.fdkankan.model.constants.ConstantFilePath;
 import com.fdkankan.model.constants.UploadFilePath;
 import com.fdkankan.rabbitmq.bean.BuildSceneCallMessage;
 import com.fdkankan.rabbitmq.util.RabbitMqProducer;
+import com.fdkankan.redis.util.RedisLockUtil;
 import com.fdkankan.redis.util.RedisUtil;
 import com.fdkankan.web.response.Result;
 import com.fdkankan.web.response.ResultData;
@@ -142,6 +143,9 @@ public class SceneFileBuildServiceImpl extends ServiceImpl<ISceneFileBuildMapper
     @Autowired
     private IFdkkLaserService fdkkLaserService;
 
+    @Autowired
+    private RedisLockUtil redisLockUtil;
+
     private RestTemplate restTemplate = new RestTemplate();
 
     @Override
@@ -210,16 +214,36 @@ public class SceneFileBuildServiceImpl extends ServiceImpl<ISceneFileBuildMapper
         }
 
         // 加锁
-        long incr = redisUtil.incr(String.format(RedisConstants.FOLDER_LOCK_BUILD, folderName), 1);
-        if (incr > 1) {
+        boolean lock = redisLockUtil.lock(String.format(RedisConstants.FOLDER_LOCK_BUILD, folderName), 120);
+        if (!lock) {
             throw new BusinessException(ErrorCode.FAILURE_CODE_5052);
         }
-        redisUtil.expire(String.format(RedisConstants.FOLDER_LOCK_BUILD, folderName), 120);
 
-        log.info("开始新生成build数据");
-        fileId = new SnowflakeIdGenerator(0, 0).nextId() + "";
-        log.info("新生成build数据,{}", fileId);
+        // 查找场景表
+        LambdaQueryWrapper<ScenePro> proWrapper = new LambdaQueryWrapper<>();
+        proWrapper.like(ScenePro::getDataSource, "/" + folderName).eq(ScenePro::getRecStatus, 'A');
+        ScenePro pro = sceneProService.getOne(proWrapper);
+
+        String dataSource = null;
+
+        if (!ObjectUtils.isEmpty(pro)) {
+            dataSource = pro.getDataSource();
+        } else {
+            dataSource = scenePlusService.getDataSourceLikeUnicode("/" + folderName);
+        }
+
+        if (!ObjectUtils.isEmpty(dataSource)) {
+            log.info("从数据库中查到与 fileId:{} 匹配的路径为:{}", fileId, dataSource);
+            int n = dataSource.split("/").length;
+            if (n > 1) {
+                fileId = pro.getDataSource().split("/")[n - 2];
+            }
+        }
 
+        if (ObjectUtils.isEmpty(fileId)) {
+            fileId = new SnowflakeIdGenerator(0, 0).nextId() + "";
+            log.info("新生成build数据,{}", fileId);
+        }
         sceneFileBuild = new SceneFileBuild();
         sceneFileBuild.setChildName(mac);
         sceneFileBuild.setFileId(fileId);

+ 26 - 37
src/main/java/com/fdkankan/contro/service/impl/ScenePlusServiceImpl.java

@@ -1,47 +1,22 @@
 package com.fdkankan.contro.service.impl;
 
-import cn.hutool.core.bean.BeanUtil;
-import cn.hutool.core.util.StrUtil;
-import com.alibaba.fastjson.JSONObject;
 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
-import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
-import com.fdkankan.common.constant.CameraConstant;
-import com.fdkankan.common.constant.CommonStatus;
-import com.fdkankan.common.constant.ConstantUrl;
 import com.fdkankan.common.constant.ErrorCode;
-import com.fdkankan.common.constant.SceneStatus;
-import com.fdkankan.common.exception.BusinessException;
-import com.fdkankan.common.util.FileUtils;
-import com.fdkankan.contro.entity.Camera;
-import com.fdkankan.contro.entity.CameraDetail;
-import com.fdkankan.contro.entity.SSOUser;
 import com.fdkankan.contro.entity.ScenePlus;
 import com.fdkankan.contro.entity.ScenePlusExt;
-import com.fdkankan.contro.entity.ScenePro;
 import com.fdkankan.contro.mapper.IScenePlusMapper;
 import com.fdkankan.contro.service.ICameraDetailService;
-import com.fdkankan.contro.service.ICameraService;
 import com.fdkankan.contro.service.IScenePlusExtService;
 import com.fdkankan.contro.service.IScenePlusService;
-import com.fdkankan.contro.service.ISceneProService;
-import com.fdkankan.contro.service.IUserService;
-import com.fdkankan.contro.vo.ScenePlusVO;
-import com.fdkankan.fyun.constant.FYunTypeEnum;
-import com.fdkankan.fyun.face.FYunFileServiceInterface;
-import com.fdkankan.model.constants.ConstantFilePath;
-import com.fdkankan.rabbitmq.bean.BuildSceneCallMessage;
 import com.fdkankan.web.response.ResultData;
-import java.io.File;
-import java.util.Date;
 import lombok.extern.slf4j.Slf4j;
-import org.joda.time.DateTime;
 import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.beans.factory.annotation.Value;
 import org.springframework.stereotype.Service;
+import org.springframework.util.ObjectUtils;
 
+import java.util.List;
 import java.util.Objects;
-import org.springframework.util.ObjectUtils;
 
 /**
  * <p>
@@ -89,29 +64,43 @@ public class ScenePlusServiceImpl extends ServiceImpl<IScenePlusMapper, ScenePlu
 
     @Override
     public String getDataSourceLikeUnicode(String unicode) {
-
-        ScenePlusExt scenePlusExt = scenePlusExtService.getOne(
+        // 防止plus表删除,ext表未删除
+        List<ScenePlusExt> scenePlusExts = scenePlusExtService.list(
             new LambdaQueryWrapper<ScenePlusExt>().like(ScenePlusExt::getDataSource, unicode)
                     .eq(ScenePlusExt::getRecStatus,"A"));
 
-        if(Objects.isNull(scenePlusExt)){
+        if (ObjectUtils.isEmpty(scenePlusExts)) {
             return null;
         }
 
-        return scenePlusExt.getDataSource();
+        if (scenePlusExts.size() > 1) {
+            for (ScenePlusExt scenePlusExt : scenePlusExts) {
+                ScenePlus plus = getById(scenePlusExt.getPlusId());
+                if (!ObjectUtils.isEmpty(plus) && plus.getRecStatus().equals("A")) {
+                    return scenePlusExt.getDataSource();
+                }
+            }
+        }
+        return scenePlusExts.get(0).getDataSource();
     }
 
     @Override
     public ScenePlus getByFileId(String fileId) {
+        // 防止plus表删除,ext表未删除
+        List<ScenePlusExt> scenePlusExts = scenePlusExtService.list(
+                new LambdaQueryWrapper<ScenePlusExt>().like(ScenePlusExt::getDataSource, fileId)
+                        .eq(ScenePlusExt::getRecStatus, "A"));
 
-        ScenePlusExt scenePlusExt = scenePlusExtService.getOne(
-            new LambdaQueryWrapper<ScenePlusExt>().like(ScenePlusExt::getDataSource, fileId)
-                    .eq(ScenePlusExt::getRecStatus,"A"));
-
-        if(Objects.isNull(scenePlusExt)){
+        if (ObjectUtils.isEmpty(scenePlusExts)) {
             return null;
         }
-        return this.getById(scenePlusExt.getPlusId());
+        for (ScenePlusExt scenePlusExt : scenePlusExts) {
+            ScenePlus plus = getById(scenePlusExt.getPlusId());
+            if (!ObjectUtils.isEmpty(plus) && plus.getRecStatus().equals("A")) {
+                return plus;
+            }
+        }
+        return null;
     }
 
 }

+ 2 - 2
src/main/resources/bootstrap-test.yml

@@ -2,9 +2,9 @@ spring:
   cloud:
     nacos:
       config:
-        server-addr: 172.20.1.63:8848
+        server-addr: 120.24.144.164:8848
         file-extension: yaml
-        namespace: 4dkankan-v4-prod
+        namespace: 4dkankan-v4-test
         extension-configs:
           - data-id: 4dkankan-center-modeling-control.yaml
             group: DEFAULT_GROUP