浏览代码

v4.12.0 空间绘制

dengsixing 1 年之前
父节点
当前提交
b5b7880df6

+ 5 - 0
src/main/java/com/fdkankan/scene/bean/SceneJsonBean.java

@@ -228,5 +228,10 @@ public class SceneJsonBean {
      */
     private JSONObject started;
 
+    /**
+     * 空间绘制
+     */
+    private Integer sceneDraw;
+
 
 }

+ 53 - 0
src/main/java/com/fdkankan/scene/controller/SceneEditDrawController.java

@@ -0,0 +1,53 @@
+package com.fdkankan.scene.controller;
+
+import com.fdkankan.common.constant.ErrorCode;
+import com.fdkankan.common.constant.SceneInfoReqType;
+import com.fdkankan.common.exception.BusinessException;
+import com.fdkankan.scene.annotation.CheckPermit;
+import com.fdkankan.scene.service.*;
+import com.fdkankan.scene.vo.*;
+import com.fdkankan.web.controller.BaseController;
+import com.fdkankan.web.response.ResultData;
+import lombok.extern.log4j.Log4j2;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.*;
+import org.springframework.web.multipart.MultipartFile;
+
+import java.io.IOException;
+
+/**
+ * 场景编辑管理
+ */
+@Log4j2
+@RestController
+@RequestMapping("/service/scene/edit/sceneDraw")
+public class SceneEditDrawController extends BaseController {
+
+    @Autowired
+    private ISceneDrawService sceneDrawService;
+
+    @CheckPermit
+    @GetMapping(value = "/list")
+    public ResultData listSceneDraw(@RequestParam("num") String num) throws Exception {
+        return ResultData.ok(sceneDrawService.listSceneDraw(num));
+    }
+
+    @CheckPermit
+    @PostMapping(value = "/save")
+    public ResultData saveSceneDraw(@RequestBody @Validated BaseJsonArrayParamVO param) throws Exception {
+        sceneDrawService.saveSceneDraw(param);
+        return ResultData.ok();
+    }
+
+    @CheckPermit
+    @PostMapping(value = "/delete")
+    public ResultData deleteSceneDraw(@RequestBody @Validated DeleteSidListParamVO param) throws Exception {
+        sceneDrawService.deleteSceneDraw(param);
+        return ResultData.ok();
+    }
+
+
+
+}

+ 8 - 2
src/main/java/com/fdkankan/scene/entity/SceneEditInfoExt.java

@@ -11,10 +11,10 @@ import lombok.Setter;
 
 /**
  * <p>
- * 
+ *
  * </p>
  *
- * @author 
+ * @author
  * @since 2022-03-07
  */
 @Getter
@@ -103,6 +103,12 @@ public class SceneEditInfoExt {
     private Integer cutModel;
 
     /**
+     * 是否有指示牌(0-否,1-是)
+     */
+    @TableField("scene_draw")
+    private Integer sceneDraw;
+
+    /**
      * 分享配置信息
      */
     @TableField("sns_info")

+ 20 - 0
src/main/java/com/fdkankan/scene/service/ISceneDrawService.java

@@ -0,0 +1,20 @@
+package com.fdkankan.scene.service;
+
+import com.alibaba.fastjson.JSONObject;
+import com.fdkankan.scene.vo.BaseJsonArrayParamVO;
+import com.fdkankan.scene.vo.DeleteSidListParamVO;
+
+import java.io.IOException;
+import java.util.List;
+
+public interface ISceneDrawService {
+
+    void saveSceneDraw(BaseJsonArrayParamVO param) throws Exception;
+
+    List<JSONObject> listSceneDraw(String num) throws Exception;
+
+    void deleteSceneDraw(DeleteSidListParamVO param) throws Exception;
+
+    void publicSceneDraw(String sceneNum, String bucket) throws IOException;
+
+}

+ 1 - 0
src/main/java/com/fdkankan/scene/service/impl/CutModelServiceImpl.java

@@ -147,6 +147,7 @@ public class CutModelServiceImpl implements ICutModelService {
         return ResultData.ok();
     }
 
+    @Override
     public void publicCutModel(String sceneNum, String bucket) throws IOException {
         String Key = String.format(RedisKey.SCENE_CUT_MODEL, sceneNum);
         String userEditPath = String.format(UploadFilePath.USER_EDIT_PATH, sceneNum) + "cutModel.json";

+ 244 - 0
src/main/java/com/fdkankan/scene/service/impl/SceneDrawServiceImpl.java

@@ -0,0 +1,244 @@
+package com.fdkankan.scene.service.impl;
+
+import cn.hutool.core.collection.CollUtil;
+import cn.hutool.core.io.FileUtil;
+import cn.hutool.core.util.StrUtil;
+import com.alibaba.fastjson.JSON;
+import com.alibaba.fastjson.JSONArray;
+import com.alibaba.fastjson.JSONObject;
+import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
+import com.fdkankan.common.constant.CommonStatus;
+import com.fdkankan.common.constant.ErrorCode;
+import com.fdkankan.common.constant.FileBizType;
+import com.fdkankan.common.exception.BusinessException;
+import com.fdkankan.common.util.FileUtils;
+import com.fdkankan.fyun.face.FYunFileServiceInterface;
+import com.fdkankan.model.constants.ConstantFilePath;
+import com.fdkankan.model.constants.UploadFilePath;
+import com.fdkankan.redis.constant.RedisKey;
+import com.fdkankan.redis.constant.RedisLockKey;
+import com.fdkankan.redis.util.RedisLockUtil;
+import com.fdkankan.redis.util.RedisUtil;
+import com.fdkankan.scene.bean.TagBean;
+import com.fdkankan.scene.entity.SceneEditInfoExt;
+import com.fdkankan.scene.entity.ScenePlus;
+import com.fdkankan.scene.entity.ScenePlusExt;
+import com.fdkankan.scene.service.*;
+import com.fdkankan.scene.vo.BaseJsonArrayParamVO;
+import com.fdkankan.scene.vo.DeleteFileParamVO;
+import com.fdkankan.scene.vo.DeleteSidListParamVO;
+import com.fdkankan.web.response.ResultData;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import javax.annotation.Resource;
+import java.io.IOException;
+import java.util.*;
+import java.util.stream.Collectors;
+
+@Service
+public class SceneDrawServiceImpl implements ISceneDrawService {
+
+    private final String SCENE_DRAW_JSON_NAME = "sceneDraw.json";
+
+    @Autowired
+    private IScenePlusService scenePlusService;
+    @Autowired
+    private IScenePlusExtService scenePlusExtService;
+    @Autowired
+    private RedisUtil redisUtil;
+    @Autowired
+    private RedisLockUtil redisLockUtil;
+    @Autowired
+    private ISceneEditInfoExtService sceneEditInfoExtService;
+    @Autowired
+    private ISceneEditInfoService sceneEditInfoService;
+    @Resource
+    private FYunFileServiceInterface fYunFileService;
+
+    @Override
+    public void saveSceneDraw(BaseJsonArrayParamVO param) throws Exception {
+
+        ScenePlus scenePlus = scenePlusService.getScenePlusByNum(param.getNum());
+
+        this.addOrUpdate(param.getNum(), param.getData());
+
+        //保存数据库
+        SceneEditInfoExt sceneEditInfoExt = sceneEditInfoExtService.getByScenePlusId(scenePlus.getId());
+        this.updateDb(param.getNum(), scenePlus.getId());
+
+        sceneEditInfoService.upgradeVersionById(sceneEditInfoExt.getEditInfoId());
+    }
+
+    private void updateDb(String num, Long scenePlusId){
+        //查询缓存是否包含热点数据
+        String key = String.format(RedisKey.SCENE_DRAW, num);
+        Map<String, String> map = redisUtil.hmget(key);
+        boolean hasSceneDraw= false;
+        for (Map.Entry<String, String> tagMap : map.entrySet()) {
+            if(StrUtil.isEmpty(tagMap.getValue())){
+                continue;
+            }
+            hasSceneDraw = true;
+            break;
+        }
+
+        //更改热点状态
+        sceneEditInfoExtService.update(
+                new LambdaUpdateWrapper<SceneEditInfoExt>()
+                        .set(SceneEditInfoExt::getSceneDraw, hasSceneDraw ? CommonStatus.YES.code().intValue() : CommonStatus.NO.code().intValue())
+                        .eq(SceneEditInfoExt::getScenePlusId,scenePlusId));
+    }
+
+    private void addOrUpdate(String num, List<JSONObject> data) throws Exception{
+        Map<String, String> addOrUpdateMap = new HashMap<>();
+        int i = 0;
+        for (JSONObject jsonObject : data) {
+            jsonObject.put("createTime", Calendar.getInstance().getTimeInMillis() + i++);
+            addOrUpdateMap.put(jsonObject.getString("sid"), JSON.toJSONString(jsonObject));
+        }
+
+        this.syncFileToRedis(num);
+
+        //处理新增和修改数据
+        this.addOrUpdateHandler(num, addOrUpdateMap);
+    }
+
+    private void addOrUpdateHandler(String num, Map<String, String> addOrUpdateMap){
+        if(CollUtil.isEmpty(addOrUpdateMap))
+            return;
+
+        //批量写入缓存
+        String key = String.format(RedisKey.SCENE_DRAW, num);
+        redisUtil.hmset(key, addOrUpdateMap);
+
+        //写入本地文件,作为备份
+        this.writeFile(num);
+    }
+
+    private void writeFile(String num){
+        String lockKey = String.format(RedisLockKey.LOCK_SCENE_DRAW, num);
+        String lockVal = cn.hutool.core.lang.UUID.randomUUID().toString();
+        boolean lock = redisLockUtil.lock(lockKey, lockVal, RedisKey.EXPIRE_TIME_1_MINUTE);
+        if(!lock){
+            return;
+        }
+        try{
+            String dataKey = String.format(RedisKey.SCENE_DRAW, num);
+            String sceneDrawJsonPath = String.format(ConstantFilePath.SCENE_USER_PATH_V4, num) + SCENE_DRAW_JSON_NAME;
+            if(!redisUtil.hasKey(dataKey)){
+                FileUtil.del(sceneDrawJsonPath);
+                return;
+            }
+            Map<String, String> map = redisUtil.hmget(dataKey);
+            List<JSONObject>  list = map.entrySet().stream().map(entry->JSON.parseObject(entry.getValue())).collect(Collectors.toList());
+            FileUtil.writeUtf8String(JSON.toJSONString(list), sceneDrawJsonPath);
+        }finally {
+            redisLockUtil.unlockLua(lockKey, lockVal);
+        }
+    }
+
+    private void syncFileToRedis(String num) throws Exception{
+
+        String key = String.format(RedisKey.SCENE_DRAW, num);
+        boolean exist = redisUtil.hasKey(key);
+        if(exist){
+            return;
+        }
+        String lockKey = String.format(RedisLockKey.LOCK_SCENE_DRAW, num);
+        String lockVal = cn.hutool.core.lang.UUID.randomUUID().toString();
+        boolean lock = redisLockUtil.lock(lockKey, lockVal, RedisKey.EXPIRE_TIME_1_MINUTE);
+        if(!lock){
+            throw new BusinessException(ErrorCode.SYSTEM_BUSY);
+        }
+        try{
+            exist = redisUtil.hasKey(key);
+            if(exist){
+                return;
+            }
+            String sceneDrawFilePath = String.format(ConstantFilePath.SCENE_USER_PATH_V4, num) + SCENE_DRAW_JSON_NAME;
+            String sceneDrawData = FileUtils.readUtf8String(sceneDrawFilePath);
+            if(StrUtil.isEmpty(sceneDrawData)){
+                return;
+            }
+            JSONArray tagsArr = JSON.parseArray(sceneDrawData);
+            if(CollUtil.isEmpty(tagsArr)){
+                return;
+            }
+            Map<String, String> map = new HashMap<>();
+            for (Object o : tagsArr) {
+                JSONObject jo = (JSONObject)o;
+                map.put(jo.getString("sid"), jo.toJSONString());
+            }
+            redisUtil.hmset(key, map);
+        }finally {
+            redisLockUtil.unlockLua(lockKey, lockVal);
+        }
+    }
+
+    @Override
+    public List<JSONObject> listSceneDraw(String num) throws Exception {
+        List<JSONObject> tags = new ArrayList<>();
+        this.syncFileToRedis(num);
+
+        //获取裁剪模型数据
+        String key = String.format(RedisKey.SCENE_DRAW, num);
+        List<String> list = redisUtil.hgetValues(key);
+        if(CollUtil.isNotEmpty(list)){
+            List<TagBean> sortList = list.stream().map(str -> {
+                JSONObject jsonObject = JSON.parseObject(str);
+                TagBean tagBean = new TagBean();
+                tagBean.setCreateTime(jsonObject.getLong("createTime"));
+                jsonObject.remove("createTime");
+                tagBean.setTag(jsonObject);
+                return tagBean;
+            }).collect(Collectors.toList());
+            sortList.sort(Comparator.comparingLong(TagBean::getCreateTime));
+            tags = sortList.stream().map(item -> item.getTag()).collect(Collectors.toList());
+        }
+
+        return tags;
+    }
+
+    @Override
+    public void deleteSceneDraw(DeleteSidListParamVO param) throws Exception {
+        ScenePlus scenePlus = scenePlusService.getScenePlusByNum(param.getNum());
+        List<String> deleteSidList = param.getSidList();
+        this.syncFileToRedis(param.getNum());
+        //处理删除状态数据
+        this.deleteCache(param.getNum(), deleteSidList);
+        //写入本地文件,作为备份
+        this.writeFile(param.getNum());
+        //保存数据库
+        SceneEditInfoExt sceneEditInfoExt = sceneEditInfoExtService.getByScenePlusId(scenePlus.getId());
+        this.updateDb(param.getNum(), scenePlus.getId());
+        sceneEditInfoService.upgradeVersionById(sceneEditInfoExt.getEditInfoId());
+    }
+
+    private List<String> deleteCache(String num, List<String> deleteSidList) {
+        if(CollUtil.isEmpty(deleteSidList)){
+            return null;
+        }
+
+        //从redis中加载热点数据
+        String key = String.format(RedisKey.SCENE_DRAW, num);
+        List<String> deletDataList = redisUtil.hMultiGet(key, deleteSidList);
+        if(CollUtil.isNotEmpty(deletDataList)){
+            redisUtil.hdel(key, deleteSidList.toArray());
+        }
+        return deletDataList;
+    }
+
+    @Override
+    public void publicSceneDraw(String sceneNum, String bucket) throws IOException {
+        String Key = String.format(RedisKey.SCENE_DRAW, sceneNum);
+        String userEditPath = String.format(UploadFilePath.USER_EDIT_PATH, sceneNum) + SCENE_DRAW_JSON_NAME;
+        List<String> list = redisUtil.hgetValues(Key);
+        if(CollUtil.isEmpty(list)){
+            fYunFileService.deleteFile(bucket, userEditPath);
+            return;
+        }
+        List<JSONObject> collect = list.stream().map(str -> JSON.parseObject(str)).collect(Collectors.toList());
+        fYunFileService.uploadFile(bucket, JSON.toJSONString(collect).getBytes(), userEditPath);
+    }
+}

+ 5 - 0
src/main/java/com/fdkankan/scene/service/impl/SceneEditInfoServiceImpl.java

@@ -114,6 +114,8 @@ public class SceneEditInfoServiceImpl extends ServiceImpl<ISceneEditInfoMapper,
     private ICommonService commonService;
     @Autowired
     private FYunFileConfig fYunFileConfig;
+    @Autowired
+    private ISceneDrawService sceneDrawService;
 
     @Transactional
     @Override
@@ -267,6 +269,9 @@ public class SceneEditInfoServiceImpl extends ServiceImpl<ISceneEditInfoMapper,
         //发布模型裁剪
         cutModelService.publicCutModel(num, bucket);
 
+        //发布场景绘制
+        sceneDrawService.publicSceneDraw(num, bucket);
+
         //本地写sceneJson文件
         String localSceneJsonPath = String.format(ConstantFilePath.SCENE_DATA_PATH_V4, num) + "scene.json";
         FileUtils.writeFile(localSceneJsonPath, JSON.toJSONString(sceneJson));

+ 5 - 0
src/main/java/com/fdkankan/scene/vo/SceneInfoVO.java

@@ -254,5 +254,10 @@ public class SceneInfoVO {
      */
     private JSONObject started;
 
+    /**
+     * 空间绘制
+     */
+    private Integer sceneDraw;
+
 
 }

+ 10 - 1
src/main/resources/bootstrap-dev.yml

@@ -4,7 +4,7 @@ spring:
   cloud:
     nacos:
       server-addr: 120.24.144.164:8848
-      namespace: 4dkankan-v4-test
+      namespace: 4dkankan-v4-dev
       config:
         file-extension: yaml
         namespace: ${spring.cloud.nacos.namespace}
@@ -24,8 +24,17 @@ spring:
           - data-id: common-fyun-config.yaml
             group: DEFAULT_GROUP
             refresh: true
+
+          - data-id: common-rabbitmq-config.yaml
+            group: DEFAULT_GROUP
+            refresh: true
+
+          - data-id: forest-config.yaml
+            group: DEFAULT_GROUP
+            refresh: true
       discovery:
         namespace: ${spring.cloud.nacos.namespace}
+#        namespace: public