Procházet zdrojové kódy

Merge branch 'release' into feature-slimming-nas-20220130-dsx

# Conflicts:
#	src/main/java/com/fdkankan/contro/mq/service/impl/BuildSceneServiceImpl.java
dsx před 2 roky
rodič
revize
11c4bc4a2b

+ 9 - 5
src/main/java/com/fdkankan/contro/controller/TestController.java

@@ -1,6 +1,8 @@
 package com.fdkankan.contro.controller;
 
+import com.fdkankan.contro.service.IScene3dNumService;
 import com.fdkankan.web.response.ResultData;
+import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.web.bind.annotation.GetMapping;
 import org.springframework.web.bind.annotation.RequestMapping;
 import org.springframework.web.bind.annotation.RestController;
@@ -11,17 +13,19 @@ import org.springframework.web.bind.annotation.RestController;
  * </p>
  *
  * @author dengsixing
- * @since 2022/12/13
+ * @since 2022/12/12
  **/
 @RestController
 @RequestMapping("/test")
 public class TestController {
 
+    @Autowired
+    private IScene3dNumService scene3dNumService;
+
     @GetMapping("/test")
-    public ResultData test(){
-        String test = null;
-        test.equals("");
-        return ResultData.ok();
+    public ResultData test() throws Exception {
+        String s = scene3dNumService.generateSceneNum(1);
+        return ResultData.ok(s);
     }
 
 }

+ 3 - 3
src/main/java/com/fdkankan/contro/entity/Scene3dNum.java

@@ -40,8 +40,8 @@ public class Scene3dNum implements Serializable {
     /**
      * 记录的状态,A: 生效,I: 禁用
      */
-    @TableField("num")
-    private String num;
+    @TableField("code")
+    private String code;
 
     /**
      * 更新时间
@@ -59,7 +59,7 @@ public class Scene3dNum implements Serializable {
      * A正常,I删除
      */
     @TableField("rec_status")
-    @TableLogic("A")
+    @TableLogic(value = "A", delval = "I")
     private String recStatus;
 
 

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

@@ -92,6 +92,12 @@ public class ScenePlus implements Serializable {
     private Integer recommend;
 
     /**
+     * 是否有housetype文件(0-否,1-是)
+     */
+    @TableField("house_type")
+    private Integer houseType;
+
+    /**
      * 创建时间
      */
     @TableField("create_time")

+ 16 - 44
src/main/java/com/fdkankan/contro/mq/service/impl/BuildSceneServiceImpl.java

@@ -241,7 +241,6 @@ public class BuildSceneServiceImpl implements IBuildSceneService {
             }
             scenePlus.setUpdateTime(new Date());
             scenePlus.setSceneStatus(SceneStatus.NO_DISPLAY.code());
-            scenePlusService.updateById(scenePlus);
 
             Integer videoVersion = fdageData.getInteger("videoVersion");
             //读取计算结果文件生成videosJson
@@ -293,8 +292,8 @@ public class BuildSceneServiceImpl implements IBuildSceneService {
 //            this.cachePanorama(path, sceneCode);
 
             //生成houseTypejson并上传
-            uploadFiles.entrySet().stream().filter(entry-> FileNameUtil.getName(entry.getKey()).equals("floorplan_cad.json"))
-                    .forEach(entry-> uploadHouseTypeJson(sceneCode,entry.getKey()));
+            boolean existHouseType = this.uploadHouseTypeJson(sceneCode, scenePlusExt.getDataSource());
+            scenePlus.setHouseType(existHouseType ? CommonStatus.YES.code().intValue() : CommonStatus.NO.code().intValue());
 
             //重置异步操作记录
             this.removeSceneAsynOperLog(sceneCode);
@@ -330,6 +329,9 @@ public class BuildSceneServiceImpl implements IBuildSceneService {
             commonService.uploadBuildResultData(sceneCode, path, SceneVersionType.V4.code());
 
             //删除计算目录
+            //更新场景主表
+            scenePlusService.updateById(scenePlus);
+
             CreateObjUtil.deleteFile(path.replace(ConstantFilePath.BUILD_MODEL_PATH, "/"));
 
             log.info("场景计算结果处理结束,场景码:{}", sceneCode);
@@ -771,42 +773,6 @@ public class BuildSceneServiceImpl implements IBuildSceneService {
         return uploadFile.keySet().stream().map(File::new).filter(File::exists).mapToLong(File::length).sum();
     }
 
-    private void sealScene(Long scenePlusId){
-        scenePlusService.update(
-            new LambdaUpdateWrapper<ScenePlus>()
-                .set(ScenePlus::getPayStatus, PayStatus.NO_CAPACITY.code())
-                .eq(ScenePlus::getId, scenePlusId));
-    }
-
-    /**
-     * <p>
-     双目场景更新数据库
-     * </p>
-     * @author dengsixing
-     * @date 2022/3/21
-     * @param num
-     * @param space
-     **/
-    private void updateDb4Sm(String num, long space){
-        List<ScenePlus> ScenePlusList = scenePlusService.list(
-            new LambdaQueryWrapper<ScenePlus>().select(ScenePlus::getId).eq(ScenePlus::getNum, num));
-
-        if(CollUtil.isEmpty(ScenePlusList)){
-            return ;
-        }
-
-        List<Long> sceneIds = ScenePlusList.stream().map(ScenePlus::getId).collect(Collectors.toList());
-
-        //更新场景创建时间
-        scenePlusService.update(new LambdaUpdateWrapper<ScenePlus>().in(ScenePlus::getId, sceneIds)
-            .set(ScenePlus::getSceneStatus, SceneStatus.NO_DISPLAY.code()));
-
-        //更新使用容量
-        scenePlusExtService.update(new LambdaUpdateWrapper<ScenePlusExt>().in(ScenePlusExt::getPlusId, sceneIds)
-                .set(ScenePlusExt::getSpace, space)
-                .set(ScenePlusExt::getAlgorithmTime, Calendar.getInstance().getTime()));
-    }
-
     private void updateDbPlus(int sceneSource,Long space,String videosJson, Long computeTime,boolean isObj,ScenePlusExt scenePlusExt){
 
         scenePlusExt.setSpace(space);
@@ -899,15 +865,21 @@ public class BuildSceneServiceImpl implements IBuildSceneService {
         return new Object[]{sceneEditInfo, sceneEditInfoExt, sceneEditControls};
     }
 
-    public void uploadHouseTypeJson(String num, String floorPlanCardFilePath) {
+    public boolean uploadHouseTypeJson(String num, String dataSource) {
+        String floorPlanCardFilePath = dataSource + File.separator + "results/floorplan_cad.json";
         if (!new File(floorPlanCardFilePath).exists()) {
-            log.error("floorplan_cad.json 文件不存在,文件路径:{}", floorPlanCardFilePath);
-            return;
+            log.warn("floorplan_cad.json 文件不存在,文件路径:{}", floorPlanCardFilePath);
+            return false;
         }
         JSONObject json = CreateHouseJsonUtil.createHouseTypeJsonByCad(floorPlanCardFilePath);
-        String hourseTypeJsonPath = String.format(UploadFilePath.DATA_VIEW_PATH, num) + "houseType.json";
+        if(Objects.isNull(json)){
+            return false;
+        }
+        String hourseTypeJsonPath = String.format(UploadFilePath.USER_VIEW_PATH, num) + "houseType.json";
         fYunFileService.uploadFile(json.toJSONString().getBytes(), hourseTypeJsonPath);
-        hourseTypeJsonPath = String.format(UploadFilePath.DATA_EDIT_PATH, num) + "houseType.json";
+        hourseTypeJsonPath = String.format(UploadFilePath.USER_EDIT_PATH, num) + "houseType.json";
         fYunFileService.uploadFile(json.toJSONString().getBytes(), hourseTypeJsonPath);
+
+        return true;
     }
 }

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

@@ -1,5 +1,6 @@
 package com.fdkankan.contro.schedule;
 
+import com.fdkankan.contro.service.IScene3dNumService;
 import com.fdkankan.rabbitmq.util.RabbitMqProducer;
 import com.fdkankan.rubbersheeting.ScalingService;
 import lombok.extern.log4j.Log4j2;
@@ -23,6 +24,8 @@ public class ScheduleJob {
 
     @Value("${queue.modeling.modeling-call}")
     private String queueModelingCall;
+    @Autowired
+    private IScene3dNumService scene3dNumService;
 
 
     @Scheduled(cron = "${rocketmq.autoScaling.corn:0 0/5 8-21 * * ?}")
@@ -40,4 +43,12 @@ public class ScheduleJob {
             log.error(e.getMessage());
         }
     }
+
+    /**
+     * 定时生成场景码,间隔1小时执行一次,项目启动一秒后执行一次
+     */
+    @Scheduled(fixedDelay = 60*60*1000, initialDelay = 1000)
+    public void generateSceneNum() {
+        scene3dNumService.generateSceneNumHandler();
+    }
 }

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

@@ -23,7 +23,9 @@ public interface IScene3dNumService extends IService<Scene3dNum> {
      * 从码池中取出一个场景码
      * @return
      */
-    String generateSceneNum(Integer cameraType);
+    String generateSceneNum(Integer cameraType) throws Exception;
+
+    void generateSceneNumHandler();
 
     /**
      * 批量生成场景码并放入码池

+ 76 - 58
src/main/java/com/fdkankan/contro/service/impl/Scene3dNumServiceImpl.java

@@ -1,5 +1,6 @@
 package com.fdkankan.contro.service.impl;
 
+import cn.hutool.core.collection.CollUtil;
 import cn.hutool.core.util.StrUtil;
 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
@@ -11,6 +12,7 @@ import com.fdkankan.contro.entity.Scene3dNum;
 import com.fdkankan.contro.enums.CameraTypeEnum;
 import com.fdkankan.contro.mapper.IScene3dNumMapper;
 import com.fdkankan.contro.service.IScene3dNumService;
+import com.fdkankan.dingtalk.DingTalkSendUtils;
 import com.fdkankan.redis.constant.RedisKey;
 import com.fdkankan.redis.constant.RedisLockKey;
 import com.fdkankan.redis.util.RedisLockUtil;
@@ -18,6 +20,7 @@ import com.fdkankan.redis.util.RedisUtil;
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.beans.factory.annotation.Value;
+import org.springframework.cloud.context.config.annotation.RefreshScope;
 import org.springframework.stereotype.Service;
 import org.springframework.util.CollectionUtils;
 
@@ -36,10 +39,16 @@ import java.util.stream.Collectors;
  * @author dengsixing
  * @since 2021-12-23
  */
+@RefreshScope
 @Slf4j
 @Service
 public class Scene3dNumServiceImpl extends ServiceImpl<IScene3dNumMapper, Scene3dNum> implements IScene3dNumService {
 
+    public static final String DINGTALK_MSG_PATTERN =
+        "**环境**: %s\n\n" +
+        "**标题**: %s\n\n" +
+        "**告警信息**: %s\n\n";
+
     @Autowired
     private RedisUtil redisUtil;
     @Autowired
@@ -47,54 +56,71 @@ public class Scene3dNumServiceImpl extends ServiceImpl<IScene3dNumMapper, Scene3
 
     @Value("${scene.num.cachePageSize:500}")
     private int cachePageSize;
-    @Value("${scene.num.threshold:10000}")
+    @Value("${scene.num.threshold:1000}")
     private int threshold;
-    @Value("${scene.num.prefix:V4-}")
+    @Value("${scene.num.prefix}")
     private String numPrefix;
     @Value("${scene.num.batchSize:100}")
     private int batchSize;
+    @Value("${main.url}")
+    private String mainUrl;
+
+    @Autowired
+    private DingTalkSendUtils dingTalkSendUtils;
 
     @Override
-    public String generateSceneNum(Integer cameraType){
+    public String generateSceneNum(Integer cameraType) throws Exception {
         // 从缓存中获取
         String sceneNum = redisUtil.lLeftPop(RedisKey.FDKANKAN_SCENE_NUMS);
         if(Objects.nonNull(sceneNum)){
             return addPrefix(sceneNum,cameraType);
         }
+        //为了防止场景量暴增导致定时任务来还不急处理,如果上面redis获取不到,需要调用一下生成场景码方法
+        log.warn("定时任务没有生成足够的场景码,此处实时调用批量生成场景码程序");
+        this.generateSceneNumHandler();
+        Thread.sleep(5000L);
+        // 从缓存中获取
+        sceneNum = redisUtil.lLeftPop(RedisKey.FDKANKAN_SCENE_NUMS);
+        if(Objects.isNull(sceneNum)){
+            String content = String.format(this.DINGTALK_MSG_PATTERN, mainUrl, "场景码穷尽告警", "场景计算获取场景码失败");
+            dingTalkSendUtils.sendActioncardMsgToDingRobot(content, "场景码穷尽告警");
+            throw new Exception("场景计算获取场景码失败");
+        }
+        return addPrefix(sceneNum,cameraType);
+    }
+
+    @Override
+    public void generateSceneNumHandler() {
+        boolean lock =  redisLockUtil.lock(RedisLockKey.LOCK_FDKANKAN_SCENE_NUMS, RedisKey.EXPIRE_TIME_30_MINUTE);
+        if(!lock){
+            return;
+        }
         // 分布式加锁
-        boolean lock =  redisLockUtil.lock(RedisLockKey.LOCK_FDKANKAN_SCENE_NUMS, RedisKey.EXPIRE_TIME_10_MINUTE);
-        if (lock) {
-            try {
-                log.info("开始加载场景码缓存");
-                List<String> nums = this.findSceneNum(cachePageSize);
-                if(CollectionUtils.isEmpty(nums)){
-                    batchCreateSceneNum(true);
-                    nums = this.findSceneNum(cachePageSize);
-                }else{
-                    CompletableFuture.runAsync(() -> batchCreateSceneNum(false));
-                }
+        try {
+            //检查mysql码池中是否有足够的未使用场景,不够时,需要创建一批
+            batchCreateSceneNum(false);
+
+            //检查redis中场景码是否少于指定缓存数量,少于时,需要从码池中获取
+            long redisCnt = redisUtil.lGetSize(RedisKey.FDKANKAN_SCENE_NUMS);
+            if(redisCnt >= cachePageSize){
+                return;
+            }
+            log.info("开始加载场景码缓存");
+            List<String> nums = this.findSceneNum(cachePageSize);
+            if(CollUtil.isEmpty(nums) || nums.size() < cachePageSize){
+                String content = String.format(this.DINGTALK_MSG_PATTERN, mainUrl, "场景码穷尽告警", "场景码表中未使用状态少于" + cachePageSize);
+                dingTalkSendUtils.sendActioncardMsgToDingRobot(content, "场景码穷尽告警");
+            }
+            if(CollUtil.isNotEmpty(nums)){
                 redisUtil.lRightPushAll(RedisKey.FDKANKAN_SCENE_NUMS, nums);
                 this.updateUsedStatus(nums);
-                log.info("场景码加载缓存完成");
-            } catch (Exception e) {
-                log.error("场景码加载缓存失败", e);
-            } finally {
-                redisLockUtil.unlockLua(RedisLockKey.LOCK_FDKANKAN_SCENE_NUMS);
             }
-        }else{
-            // 等待2秒加载缓存
-            try {
-                Thread.sleep(2000);
-            } catch (InterruptedException e) {
-                log.error("场景码加载缓存失败", e);
-            }
-        }
-        sceneNum = redisUtil.lLeftPop(RedisKey.FDKANKAN_SCENE_NUMS);
-        if(StrUtil.isEmpty(sceneNum)){
-            log.error("场景码加载失败");
-            throw new BusinessException(ErrorCode.FAILURE_CODE_5053);
+            log.info("场景码加载缓存完成");
+        } catch (Exception e) {
+            log.error("场景码加载缓存失败", e);
+        } finally {
+            redisLockUtil.unlockLua(RedisLockKey.LOCK_FDKANKAN_SCENE_NUMS);
         }
-        return addPrefix(sceneNum,cameraType);
     }
 
     private  static  String addPrefix( String num,Integer cameraType){
@@ -106,34 +132,26 @@ public class Scene3dNumServiceImpl extends ServiceImpl<IScene3dNumMapper, Scene3
 
     @Override
     public void batchCreateSceneNum(boolean force) {
-        String lockKey = String.format(RedisLockKey.LOCK_BATCH_CREATE_NUM);
-        boolean lock = redisLockUtil.lock(lockKey, RedisKey.EXPIRE_TIME_10_MINUTE);
-        if(!lock){
-            return;
-        }
-        try {
-            if (!force) {
-                long count = this.count(new LambdaQueryWrapper<Scene3dNum>().eq(Scene3dNum::getUsed, CommonStatus.NO.code()));
-                if (count > threshold) {
-                    return;
-                }
+        if (!force) {
+            long count = this.count(new LambdaQueryWrapper<Scene3dNum>().eq(Scene3dNum::getUsed, CommonStatus.NO.code()));
+            if (count > threshold) {
+                return;
             }
-            int batchCnt = threshold / batchSize + (threshold % batchSize > 0 ? 1 : 0);
-            for (int i = 0; i < batchCnt; i++){
-                Set<String> numSet = this.turnCreateSceneNum(batchSize);
-                List<Scene3dNum> scene3dNumList = numSet.parallelStream().map(num -> {
-                    Scene3dNum scene3dNum = new Scene3dNum();
-                    scene3dNum.setNum(num);
-                    return scene3dNum;
-                }).collect(Collectors.toList());
-                try{
-                    this.saveBatch(scene3dNumList);
-                }catch (Exception e){
-                    log.error("场景码插入异常!",e);
-                }
+        }
+        int batchCnt = threshold / batchSize + (threshold % batchSize > 0 ? 1 : 0);//批次数
+        for (int i = 0; i < batchCnt; i++){//分批生成,每批次batchSize个
+            Set<String> numSet = this.turnCreateSceneNum(batchSize);
+            List<Scene3dNum> scene3dNumList = numSet.parallelStream().map(num -> {
+                Scene3dNum scene3dNum = new Scene3dNum();
+                scene3dNum.setCode(num);
+                return scene3dNum;
+            }).collect(Collectors.toList());
+            try{
+                this.saveBatch(scene3dNumList);
+            }catch (Exception e){
+                log.error("场景码插入异常!");
+                e.printStackTrace();
             }
-        }finally {
-            redisLockUtil.unlockLua(lockKey);
         }
     }