dengsixing 3 gadi atpakaļ
vecāks
revīzija
7aed802f1a

+ 2 - 2
4dkankan-center-scene/src/main/java/com/fdkankan/scene/controller/SceneEditController.java

@@ -1015,8 +1015,8 @@ public class SceneEditController extends BaseController {
      */
     @CheckCooperationPermit
     @PostMapping(value = "/mosaics/delete")
-    public ResultData deleteMosaic(@RequestBody @Validated BaseDataParamVO param) throws Exception{
-        return sceneEditInfoService.addMosaics(param);
+    public ResultData deleteMosaics(@RequestBody @Validated DeleteMosaicParamVO param) throws Exception{
+        return sceneEditInfoService.deleteMosaics(param);
     }
 
     /**

+ 3 - 1
4dkankan-center-scene/src/main/java/com/fdkankan/scene/service/ISceneEditInfoService.java

@@ -68,7 +68,7 @@ public interface ISceneEditInfoService extends IService<SceneEditInfo> {
 
     ResultData checkKey(SceneCheckKeyParamVO param) throws Exception;
 
-    ResultData addMosaics(@RequestBody @Validated BaseDataParamVO param) throws Exception;
+    ResultData addMosaics(BaseDataParamVO param) throws Exception;
 
     ResultData uploadLinkPan(String num, String sid, String fileName, MultipartFile file) throws Exception;
 
@@ -80,6 +80,8 @@ public interface ISceneEditInfoService extends IService<SceneEditInfo> {
 
     ResultData deleteStyles(DeleteLinkSceneStylesParamVO param) throws Exception;
 
+    ResultData deleteMosaics(DeleteMosaicParamVO param) throws Exception;
+
 
 
 

+ 107 - 2
4dkankan-center-scene/src/main/java/com/fdkankan/scene/service/impl/SceneEditInfoServiceImpl.java

@@ -1550,6 +1550,9 @@ public class SceneEditInfoServiceImpl extends ServiceImpl<ISceneEditInfoMapper,
     @Override
     public ResultData addMosaics(BaseDataParamVO param) throws Exception {
 
+        //如果redis数据丢失,从本地文件中同步马赛克数据到redis
+        this.syncMosaicFromFileToRedis(param.getNum());
+
         Map<String, String> map = new HashMap<>();
         JSONArray jsonArray = JSON.parseArray(param.getData());
         for (Object o : jsonArray) {
@@ -1560,9 +1563,85 @@ public class SceneEditInfoServiceImpl extends ServiceImpl<ISceneEditInfoMapper,
             }
             map.put(panoId, JSON.toJSONString(mosaic));
         }
-        redisUtil.hmset(RedisKey.SCENE_MOSAIC_DATA, map);
+        String key = String.format(RedisKey.SCENE_MOSAIC_DATA, param.getNum());
+        redisUtil.hmset(key, map);
 
-        return ResultData.ok(result);
+        //写入本地文件,作为备份
+        this.writeMosaic(param.getNum());
+
+        return ResultData.ok();
+    }
+
+    /**
+     * <p>
+     保证马赛克数据安全性,当redis宕机导致热点数据丢失时,可以从文件中读取,恢复到redis
+     **/
+    private void syncMosaicFromFileToRedis(String num) throws Exception{
+
+        String key = String.format(RedisKey.SCENE_MOSAIC_DATA, num);
+        boolean exist = redisUtil.hasKey(key);
+        if(exist){
+            return;
+        }
+        String lockKey = String.format(RedisLockKey.LOCK_MOSAIC_DATA_SYNC, num);
+        boolean lock = redisLockUtil.lock(lockKey, RedisKey.EXPIRE_TIME_1_MINUTE);
+        if(!lock){
+            throw new BusinessException(ErrorCode.SYSTEM_BUSY);
+        }
+        try{
+            exist = redisUtil.hasKey(key);
+            if(exist){
+                return;
+            }
+            String filePath = String.format(ConstantFilePath.SCENE_USER_PATH_V4, num);
+            String mosaicData = FileUtils.readFile(filePath + "mosaic.json");
+            if(StrUtil.isEmpty(mosaicData)){
+                return;
+            }
+            JSONArray jsonArray = JSON.parseArray(mosaicData);
+            if(CollUtil.isEmpty(jsonArray)){
+                return;
+            }
+            Map<String, String> map = new HashMap<>();
+            for (Object o : jsonArray) {
+                JSONObject jo = (JSONObject)o;
+                map.put(jo.getString("panoId"), jo.toJSONString());
+            }
+            redisUtil.hmset(key, map);
+        }finally {
+            redisLockUtil.unlockLua(lockKey);
+        }
+    }
+
+    /**
+     * <p>
+     保证马赛克数据安全性,当redis宕机导致热点数据丢失时,可以从文件中读取,恢复到redis
+     **/
+    private void writeMosaic(String num) throws Exception{
+
+        String key = String.format(RedisKey.SCENE_MOSAIC_DATA, num);
+        Map<String, String> mosaicMap = redisUtil.hmget(key);
+        if(CollUtil.isEmpty(mosaicMap)){
+            return;
+        }
+        List<String> mosaicList = Lists.newArrayList(mosaicMap.values());
+        JSONArray jsonArr = new JSONArray();
+        mosaicList.stream().forEach(mosaic->{
+            jsonArr.add(JSONObject.parseObject(mosaic));
+        });
+
+
+        String mosaicPath = String.format(ConstantFilePath.SCENE_USER_PATH_V4, num) + "mosaic.json";
+        String lockKey = String.format(RedisLockKey.LOCK_MOSAIC_JSON, num);
+        boolean lock = redisLockUtil.lock(lockKey, RedisKey.EXPIRE_TIME_1_MINUTE);
+        if(!lock){
+            return;
+        }
+        try{
+            FileUtils.writeFile(mosaicPath, jsonArr.toJSONString());
+        }finally {
+            redisLockUtil.unlockLua(lockKey);
+        }
     }
 
     @Override
@@ -2291,4 +2370,30 @@ public class SceneEditInfoServiceImpl extends ServiceImpl<ISceneEditInfoMapper,
         uploadToOssUtil.upload(localFilePath.replace("mp4", "flv"), userEditPath+flvFileName);
     }
 
+    @Override
+    public ResultData deleteMosaics(DeleteMosaicParamVO param) throws Exception {
+
+        //如果redis数据丢失,从本地文件中同步马赛克数据到redis
+        this.syncMosaicFromFileToRedis(param.getNum());
+
+        Map<String, String> map = new HashMap<>();
+        JSONArray jsonArray = JSON.parseArray(param.getData());
+        for (Object o : jsonArray) {
+            JSONObject mosaic = (JSONObject) o;
+            String panoId = mosaic.getString("panoId");
+            if(StrUtil.isEmpty(panoId)){
+                throw  new BusinessException(ErrorCode.FAILURE_CODE_5012);
+            }
+            map.put(panoId, JSON.toJSONString(mosaic));
+        }
+        redisUtil.hmset(RedisKey.SCENE_MOSAIC_DATA, map);
+
+        //写入本地文件,作为备份
+        this.writeMosaic(param.getNum());
+
+        return ResultData.ok();
+
+
+        return null;
+    }
 }

+ 1 - 0
4dkankan-center-scene/src/main/java/com/fdkankan/scene/vo/BaseDataParamVO.java

@@ -1,5 +1,6 @@
 package com.fdkankan.scene.vo;
 
+import com.fdkankan.redis.constant.RedisKey;
 import javax.validation.constraints.NotBlank;
 import javax.validation.constraints.NotNull;
 import lombok.Data;

+ 28 - 0
4dkankan-center-scene/src/main/java/com/fdkankan/scene/vo/DeleteMosaicParamVO.java

@@ -0,0 +1,28 @@
+package com.fdkankan.scene.vo;
+
+import java.util.List;
+import javax.validation.constraints.NotBlank;
+import javax.validation.constraints.NotNull;
+import lombok.Data;
+
+/**
+ * <p>
+        删除马赛克入参
+ * </p>
+ * @author dengsixing
+ * @date 2022/7/12
+ * @param null
+ * @return null
+ **/
+@Data
+public class DeleteMosaicParamVO {
+
+    @NotBlank(message = "场景码不能为空")
+    private String num;
+
+    @NotNull(message = "panoIdList不能为空")
+    private List<String> panoIdList;
+
+
+
+}