Browse Source

场景复制

lyhzzz 2 years ago
parent
commit
aa978c30cd

+ 48 - 32
src/main/java/com/fdkankan/ucenter/bean/SceneJsonBean.java

@@ -1,12 +1,15 @@
 package com.fdkankan.ucenter.bean;
 
 import com.alibaba.fastjson.JSONObject;
-import java.util.Date;
+import com.fdkankan.ucenter.vo.SceneEditControlsVO;
 import lombok.AllArgsConstructor;
 import lombok.Builder;
 import lombok.Data;
 import lombok.NoArgsConstructor;
 
+import java.util.Date;
+import java.util.List;
+
 /**
  * <p>
  * scene.json实体类
@@ -66,28 +69,28 @@ public class SceneJsonBean {
      */
     private String description;
 
-    private SceneEditControlsBean controls;
+    private SceneEditControlsVO controls;
 
     /**
      * 创建时间
      */
-    private Date createTime;
-
-//    /**
-//     * 点位数量
-//     */
-//    private Integer panoCount;
-//
-//    /**
-//     * 球幕视频数量
-//     */
-//    private Integer videoCount;
+    private String createTime;
 
     /**
      * 版本
      */
     private Integer version;
 
+    /**
+     * 图片版本
+     */
+    private Integer imgVersion;
+
+    /**
+     * 场景关联版本
+     */
+    private Integer linkVersion;
+
 //    /**
 //     * 户型图文件路径集合
 //     */
@@ -98,23 +101,6 @@ public class SceneJsonBean {
      */
     private Byte floorPlanUser;
 
-//    private String cadInfo;
-
-//    /**
-//     * 是否上传模型
-//     */
-//    private Byte isUploadObj;
-//
-//    /**
-//     * 重新建模的版本
-//     */
-//    private Integer floorEditVer;
-//
-//    /**
-//     * 正式发布重新建模的版本
-//     */
-//    private Integer floorPublishVer;
-
     /**
      * 初始点信息
      */
@@ -136,14 +122,19 @@ public class SceneJsonBean {
     private String sceneKind;
 
     /**
-     * 视频覆盖数据
+     * 空间视频数据
      */
     private String boxVideos;
 
     /**
+     * 空间贴图数据
+     */
+    private String boxPhotos;
+
+    /**
      *点位视频
      */
-    private JSONObject videos;
+    private String videos;
 
     /**
      * 是否有热点数据
@@ -160,6 +151,8 @@ public class SceneJsonBean {
      */
     private String loadingLogoFile;
 
+    private Integer payStatus;
+
     /**
      * 户型角度
      */
@@ -170,7 +163,30 @@ public class SceneJsonBean {
      */
     private Float floorPlanCompass;
 
+    /**
+     * 是否保存导览
+     */
+    private Integer tours;
 
+    /**
+     * 是否有场景关联(0-否,1-是)
+     */
+    private Integer links;
+
+    /**
+     * 是否有马赛克
+     */
+    private Integer mosaic;
+
+    /**
+     * 马赛克列表
+     */
+    private List<JSONObject> mosaicList;
+
+    /**
+     * 水印文件名
+     */
+    private String waterMark;
 
 
 }

+ 5 - 0
src/main/java/com/fdkankan/ucenter/service/ISceneEditInfoService.java

@@ -1,8 +1,11 @@
 package com.fdkankan.ucenter.service;
 
+import com.alibaba.fastjson.JSONObject;
 import com.fdkankan.ucenter.entity.SceneEditInfo;
 import com.baomidou.mybatisplus.extension.service.IService;
 
+import java.util.List;
+
 /**
  * <p>
  *  服务类
@@ -14,4 +17,6 @@ import com.baomidou.mybatisplus.extension.service.IService;
 public interface ISceneEditInfoService extends IService<SceneEditInfo> {
 
     SceneEditInfo getByScenePlusId(Long plusId);
+
+    List<JSONObject> getMosaicList(String num) throws Exception;
 }

+ 1 - 1
src/main/java/com/fdkankan/ucenter/service/IScenePlusService.java

@@ -34,7 +34,7 @@ public interface IScenePlusService extends IService<ScenePlus> {
 
     ScenePlus getByNum(String sceneNum);
 
-    void copyV4Scene(ScenePlus scenePlus,String newNum, CameraDetail cameraDetail) throws IOException, Exception;
+    Long copyV4Scene(ScenePlus scenePlus,String newNum, CameraDetail cameraDetail,String time) throws IOException, Exception;
 
     List<ScenePlus> getByIds(List<Long> plusIds);
 }

+ 10 - 11
src/main/java/com/fdkankan/ucenter/service/ISceneProService.java

@@ -25,7 +25,7 @@ public interface ISceneProService extends IService<ScenePro> {
 
     HashMap<String, SceneNumVo> findSceneNumber(String token);
 
-    HashMap<Long, GroupByCount>findSceneNumByCameraIds(List<Long> cameraIdList);
+    HashMap<Long, GroupByCount> findSceneNumByCameraIds(List<Long> cameraIdList);
 
     void lockOrUnLockBySpace(CameraDetail cameraDetail, Long cameraId, int payStatus);
 
@@ -39,19 +39,18 @@ public interface ISceneProService extends IService<ScenePro> {
 
     Long getCountByUserId(Long id, List<Integer> resourceList);
 
-    Long getCountByUserId(Long id, Integer cameraType) ;
+    Long getCountByUserId(Long id, Integer cameraType);
 
     void deleteByIds(List<Long> sceneIds);
 
     JSONObject newList(SceneParam param, String username);
 
-    void copyScene(String sceneNum,String userName) throws Exception;
+    void copyScene(String sceneNum, String userName) throws Exception;
 
     ScenePro getByNum(String sceneNum);
 
-    void copyV3Scene(ScenePro scenePro,String newNum,CameraDetail cameraDetail) throws Exception;
+    Long copyV3Scene(ScenePro scenePro, String newNum, CameraDetail cameraDetail, String time) throws Exception;
 
-    void updateSceneJson(String type,String videos,String newNum,String sceneName,String webSite,String thumb,Long id) throws Exception;
 
     void delete(String sceneNum);
 
@@ -65,15 +64,15 @@ public interface ISceneProService extends IService<ScenePro> {
 
     ScenePro findByFileId(String fileId);
 
-    void setQrCode(String buildType,String num) throws Exception ;
+    void setQrCode(String buildType, String num) throws Exception;
 
-    void copyOssSource(String type ,String sceneNum, String newNum) throws Exception ;
-
-    void copyLocalSource(String sceneNum, String newNum) throws Exception ;
-
-    String setDataSource(String preDataSource,Integer sceneSource) throws Exception;
+    String setDataSource(String preDataSource, String time) throws Exception;
 
     void generateObjFile(String num);
 
     void updateDbViewCount(String num, String count);
+
+    String setVideos(String videos, String oldNum, String newNum);
+
+     void copyFdage(String oldDataSource, String newDataSource, String buildModelPath, String time) throws Exception;
 }

+ 117 - 0
src/main/java/com/fdkankan/ucenter/service/impl/SceneEditInfoServiceImpl.java

@@ -1,12 +1,33 @@
 package com.fdkankan.ucenter.service.impl;
 
+import cn.hutool.core.collection.CollUtil;
+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.query.LambdaQueryWrapper;
+import com.fdkankan.common.constant.ErrorCode;
+import com.fdkankan.common.exception.BusinessException;
+import com.fdkankan.common.util.FileUtils;
+import com.fdkankan.model.constants.ConstantFilePath;
+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.ucenter.common.ResultData;
 import com.fdkankan.ucenter.entity.SceneEditInfo;
 import com.fdkankan.ucenter.mapper.ISceneEditInfoMapper;
 import com.fdkankan.ucenter.service.ISceneEditInfoService;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.google.common.collect.Lists;
+import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.stream.Collectors;
+
 /**
  * <p>
  *  服务实现类
@@ -18,9 +39,105 @@ import org.springframework.stereotype.Service;
 @Service
 public class SceneEditInfoServiceImpl extends ServiceImpl<ISceneEditInfoMapper, SceneEditInfo> implements ISceneEditInfoService {
 
+    @Autowired
+    RedisUtil redisUtil;
+    @Autowired
+    private RedisLockUtil redisLockUtil;
+
+
     @Override
     public SceneEditInfo getByScenePlusId(Long plusId) {
         return this.getOne(new LambdaQueryWrapper<SceneEditInfo>()
                 .eq(SceneEditInfo::getScenePlusId, plusId));
     }
+
+    @Override
+    public List<JSONObject> getMosaicList(String num) throws Exception {
+        //如果redis数据丢失,从本地文件中同步马赛克数据到redis
+        this.syncMosaicFromFileToRedis(num);
+
+        String key = String.format(RedisKey.SCENE_MOSAIC_DATA, num);
+        Map<String, String> map = redisUtil.hmget(key);
+        if(CollUtil.isEmpty(map)){
+            ResultData.ok(new String[0]);
+        }
+        return map.values().stream()
+                .map(mosaic-> JSON.parseObject(mosaic))
+                .collect(Collectors.toList());
+    }
+
+
+    /**
+     * <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 mosaicPath = String.format(ConstantFilePath.SCENE_USER_PATH_V4, num) + "mosaic.json";
+
+        String key = String.format(RedisKey.SCENE_MOSAIC_DATA, num);
+        Map<String, String> mosaicMap = redisUtil.hmget(key);
+        if(CollUtil.isEmpty(mosaicMap)){
+            FileUtils.deleteFile(mosaicPath);
+            return;
+        }
+        List<String> mosaicList = Lists.newArrayList(mosaicMap.values());
+        JSONArray jsonArr = new JSONArray();
+        mosaicList.stream().forEach(mosaic->{
+            jsonArr.add(JSONObject.parseObject(mosaic));
+        });
+
+
+        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);
+        }
+    }
 }

+ 136 - 45
src/main/java/com/fdkankan/ucenter/service/impl/ScenePlusServiceImpl.java

@@ -1,8 +1,19 @@
 package com.fdkankan.ucenter.service.impl;
 
+import cn.hutool.core.bean.BeanUtil;
+import cn.hutool.core.util.StrUtil;
+import com.alibaba.fastjson.JSON;
 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.util.FileUtils;
+import com.fdkankan.fyun.face.FYunFileServiceInterface;
+import com.fdkankan.image.MatrixToImageWriterUtil;
+import com.fdkankan.model.constants.ConstantFilePath;
+import com.fdkankan.model.constants.UploadFilePath;
+import com.fdkankan.redis.constant.RedisKey;
+import com.fdkankan.redis.util.RedisUtil;
+import com.fdkankan.ucenter.bean.SceneJsonBean;
 import com.fdkankan.ucenter.entity.CameraDetail;
 import com.fdkankan.ucenter.entity.SceneEditControls;
 import com.fdkankan.ucenter.entity.SceneEditInfo;
@@ -18,11 +29,21 @@ import com.fdkankan.ucenter.service.ISceneEditInfoService;
 import com.fdkankan.ucenter.service.IScenePlusExtService;
 import com.fdkankan.ucenter.service.IScenePlusService;
 import com.fdkankan.ucenter.service.ISceneProService;
+
+import java.io.File;
+import java.util.Date;
 import java.util.HashMap;
 import java.util.List;
+import java.util.concurrent.CompletableFuture;
+
+import com.fdkankan.ucenter.vo.SceneEditControlsVO;
+import lombok.extern.slf4j.Slf4j;
 import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
 import org.springframework.stereotype.Service;
 
+import javax.annotation.Resource;
+
 /**
  * <p>
  * 场景主表 服务实现类
@@ -32,6 +53,7 @@ import org.springframework.stereotype.Service;
  * @since 2022-07-04
  */
 @Service
+@Slf4j
 public class ScenePlusServiceImpl extends ServiceImpl<IScenePlusMapper, ScenePlus> implements IScenePlusService {
 
     @Autowired
@@ -48,6 +70,15 @@ public class ScenePlusServiceImpl extends ServiceImpl<IScenePlusMapper, ScenePlu
     private ISceneCopyLogService sceneCopyLogService;
     @Autowired
     private ISceneProService sceneProService;
+    @Resource
+    FYunFileServiceInterface fYunFileServiceInterface;
+    @Autowired
+    RedisUtil redisUtil;
+
+    @Value("${main.url}")
+    private String mainUrl;
+    @Value("${scene.pro.new.url}")
+    private String sceneProNewUrl;
 
     @Override
     public Long getCountByUserId(Long userId, List<Integer> sceneSourceList) {
@@ -121,67 +152,127 @@ public class ScenePlusServiceImpl extends ServiceImpl<IScenePlusMapper, ScenePlu
     }
 
     @Override
-    public void copyV4Scene(ScenePlus scenePlus,String newNum, CameraDetail cameraDetail) throws Exception {
+    public Long copyV4Scene(ScenePlus scenePlus,String newNum ,CameraDetail cameraDetail,String time) throws Exception {
         String num = scenePlus.getNum();
         Long plusId = scenePlus.getId();
-        scenePlus.setSceneStatus(0);
+        ScenePlusExt plusExt = scenePlusExtService.getByPlusId(plusId);
+
+        // 拷贝数据
         scenePlus.setNum(newNum);
         scenePlus.setId(null);
-        scenePlus.setTitle(scenePlus.getTitle().concat("(copy)"));
         this.save(scenePlus);
 
-        ScenePlusExt plusExt = scenePlusExtService.getByPlusId(plusId);
-        String videos ;
-        if(plusExt.getVideos().contains("scene_view_data")){
-            videos = plusExt.getVideos().replace(num,newNum);
-        }else {
-            videos = plusExt.getVideos().replaceAll("https://4dkk.4dage.com/data/data"+num, "https://4dkk.4dage.com/scene_view_data/"+newNum+"/data");
-        }
+        cameraDetail.setUsedSpace(cameraDetail.getUsedSpace() + plusExt.getSpace());
+        cameraDetailService.updateById(cameraDetail);
 
-        plusExt.setId(null);
-        plusExt.setPlusId(scenePlus.getId());
-        plusExt.setWebSite(plusExt.getWebSite().replace(num,newNum));
-        plusExt.setThumb(plusExt.getThumb().replace(num,newNum));
-        plusExt.setVideos(videos);
-        plusExt.setViewCount(0);
+        CompletableFuture.runAsync(() -> {
+            try {
+                // 拷贝场景编辑资源
+                String oldEditPath = String.format(UploadFilePath.EDIT_PATH, num);
+                String newEditPath = String.format(UploadFilePath.EDIT_PATH, newNum);
+                fYunFileServiceInterface.copyFileInBucket(oldEditPath, newEditPath);
 
-        String newDataSource = sceneProService.setDataSource(plusExt.getDataSource(), scenePlus.getSceneSource());
-        plusExt.setDataSource(newDataSource);
-        scenePlusExtService.save(plusExt);
+                // 拷贝场景展示资源
+                String oldViewPath = String.format(UploadFilePath.VIEW_PATH, num);
+                String newViewPath = String.format(UploadFilePath.VIEW_PATH, newNum);
+                fYunFileServiceInterface.copyFileInBucket(oldViewPath, newViewPath);
+                // 拷贝本地资源
+                String oldPath = String.format("/mnt/4Dkankan/scene/%s/caches/images/", num);
+                String newPath = String.format("/mnt/4Dkankan/scene/%s/caches/images/", newNum);
+                if(new File(oldPath).exists()){
+                    FileUtils.copyDirectiory(oldPath, newPath);
+                }
 
-        //保存复制日志
-        sceneCopyLogService.saveByNum(num,newNum,scenePlus.getUserId());
-        //复制完成更新相机容量
-        cameraDetail.setUsedSpace(cameraDetail.getUsedSpace() + plusExt.getSpace());
-        cameraDetailService.updateById(cameraDetail);
+                String scenePath = ConstantFilePath.SCENE_V4_PATH + num;
+                File file = new File(scenePath);
+                if(file.exists()){
+                    String newScenePath = ConstantFilePath.SCENE_V4_PATH + newNum;
+                    FileUtils.copyDirectiory(scenePath, newScenePath);
+                }
+
+
+                String newVideos = plusExt.getVideos().replaceAll("https://4dkk.4dage.com/data/data" + num, "https://4dkk.4dage.com/scene_view_data/" + newNum + "/data");
+                String oldDataSource  = plusExt.getDataSource();
+                String newDataSource =  sceneProService.setDataSource(plusExt.getDataSource(),time);
+
+                String buildModelPath = ConstantFilePath.BUILD_MODEL_PATH;
+                if(scenePlus.getSceneSource().equals(4)){
+                    buildModelPath = ConstantFilePath.BUILD_MODEL_LASER_PATH;
+                }
+                sceneProService.copyFdage(oldDataSource,newDataSource,buildModelPath,time);
+
+                plusExt.setId(null);
+                plusExt.setPlusId(scenePlus.getId());
+                plusExt.setDataSource(newDataSource);
+                plusExt.setWebSite(plusExt.getWebSite().replace(num, newNum));
+                plusExt.setThumb(plusExt.getThumb().replace(num, newNum));
+                plusExt.setVideos(newVideos);
+                scenePlusExtService.save(plusExt);
+
+                SceneEditInfo sceneEditInfo = sceneEditInfoService.getByScenePlusId(plusId);
+                Long sceneEditInfoId = sceneEditInfo.getId();
+
+                sceneEditInfo.setId(null);
+                sceneEditInfo.setScenePlusId(scenePlus.getId());
+                sceneEditInfo.setSceneProId(null);
+                sceneEditInfo.setTitle(scenePlus.getTitle());
+                sceneEditInfoService.save(sceneEditInfo);
 
+                SceneEditInfoExt sceneEditInfoExt = sceneEditInfoExtService.getByEditInfoId(sceneEditInfoId);
+                sceneEditInfoExt.setId(null);
+                sceneEditInfoExt.setEditInfoId(sceneEditInfo.getId());
+                sceneEditInfoExt.setScenePlusId(scenePlus.getId());
+                sceneEditInfoExt.setSceneProId(null);
+                sceneEditInfoExtService.save(sceneEditInfoExt);
 
-        SceneEditInfo sceneEditInfo = sceneEditInfoService.getByScenePlusId(plusId);
-        Long sceneEditInfoId = sceneEditInfo.getId();
+                SceneEditControls sceneEditControls = sceneEditControlsService.getBySceneEditId(sceneEditInfoId);
+                sceneEditControls.setId(null);
+                sceneEditControls.setEditInfoId(sceneEditInfo.getId());
+                sceneEditControlsService.save(sceneEditControls);
 
-        sceneEditInfo.setId(null);
-        sceneEditInfo.setScenePlusId(scenePlus.getId());
-        sceneEditInfo.setTitle(scenePlus.getTitle());
-        sceneEditInfoService.save(sceneEditInfo);
+                // 生成scene.json
+                SceneJsonBean sceneJson = new SceneJsonBean();
+                BeanUtil.copyProperties(sceneEditInfoExt, sceneJson);
+                BeanUtil.copyProperties(sceneEditInfo, sceneJson);
+                SceneEditControlsVO sceneEditControlsVO = BeanUtil.copyProperties(sceneEditControls, SceneEditControlsVO.class);
+                sceneJson.setControls(sceneEditControlsVO);
+                sceneJson.setNum(newNum);
+                sceneJson.setCreateTime(scenePlus.getCreateTime());
 
-        SceneEditInfoExt sceneEditInfoExt = sceneEditInfoExtService.getByEditInfoId(sceneEditInfoId);
-        sceneEditInfoExt.setId(null);
-        sceneEditInfoExt.setEditInfoId(sceneEditInfo.getId());
-        sceneEditInfoExt.setScenePlusId(scenePlus.getId());
-        sceneEditInfoExtService.save(sceneEditInfoExt);
+                sceneJson.setSceneResolution(plusExt.getSceneResolution());
+                sceneJson.setSceneFrom(plusExt.getSceneFrom());
+                sceneJson.setSceneKind(plusExt.getSceneKind());
+                if(StrUtil.isNotEmpty(plusExt.getVideos())){
+                    sceneJson.setVideos(plusExt.getVideos());
+                }
+                sceneJson.setMosaicList(sceneEditInfoService.getMosaicList(num));
 
-        SceneEditControls sceneEditControls = sceneEditControlsService.getBySceneEditId(sceneEditInfoId);
-        sceneEditControls.setId(null);
-        sceneEditControls.setEditInfoId(sceneEditInfo.getId());
-        sceneEditControlsService.save(sceneEditControls);
+                log.info("开始生成本地json文件……");
+                String sceneJsonLocalPath = ConstantFilePath.SCENE_PATH + "data" + File.separator + "data" + newNum + File.separator + "scene.json";
+                FileUtils.writeFile(sceneJsonLocalPath, JSON.toJSONString(sceneJson));
 
-        sceneProService.setQrCode("V3",newNum);
-        sceneProService.copyOssSource("v4",num,newNum);
-        sceneProService.copyLocalSource(num,newNum);
-        sceneProService.updateSceneJson("v4",plusExt.getVideos(),newNum,scenePlus.getTitle(),plusExt.getWebSite(),plusExt.getThumb(),scenePlus.getId());
+                String sceneJsonPath = String.format(UploadFilePath.DATA_VIEW_PATH+"scene.json", newNum);
+                fYunFileServiceInterface.uploadFile(JSON.toJSONBytes(sceneJson), sceneJsonPath);
 
-        scenePlus.setSceneStatus(-2);
-        this.updateById(scenePlus);
+                //删除scenejson缓存
+                redisUtil.del(String.format(RedisKey.SCENE_JSON, num));
 
+                // 生成二维码
+                String sceneUrl = mainUrl + "/" + sceneProNewUrl;
+                String outPathZh = ConstantFilePath.BASE_PATH + File.separator + "sceneQRcode/" + newNum + ".png";
+                String outPathEn = ConstantFilePath.BASE_PATH + File.separator + "sceneQRcode/" + newNum + "_en.png";
+                MatrixToImageWriterUtil.createQRCode(sceneUrl + newNum, outPathZh, false,null);
+                MatrixToImageWriterUtil.createQRCode(sceneUrl + newNum + "&lang=en", outPathEn, false, null);
+                fYunFileServiceInterface.uploadFile(outPathZh, String.format(UploadFilePath.DOWNLOADS_QRCODE, newNum) + newNum + ".png");
+                fYunFileServiceInterface.uploadFile(outPathEn, String.format(UploadFilePath.DOWNLOADS_QRCODE, newNum) + newNum + "_en.png");
+                scenePlus.setSceneStatus(-2);
+                this.updateById(scenePlus);
+                log.info("复制场景结束-{}", new Date());
+            }catch (Exception e){
+                this.removeById(scenePlus.getId());
+                log.error("复制场景异常", e);
+            }
+        });
+        return scenePlus.getId();
     }
 }

+ 151 - 105
src/main/java/com/fdkankan/ucenter/service/impl/SceneProServiceImpl.java

@@ -8,13 +8,11 @@ import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
 import com.fdkankan.common.constant.SceneConstant;
 import com.fdkankan.common.constant.SceneKind;
 import com.fdkankan.common.exception.BusinessException;
+import com.fdkankan.common.util.*;
 import com.fdkankan.rabbitmq.bean.BuildSceneCallMessage;
 import com.fdkankan.rabbitmq.util.RabbitMqProducer;
 import com.fdkankan.redis.constant.RedisKey;
 import com.fdkankan.ucenter.common.PageInfo;
-import com.fdkankan.common.util.FileUtils;
-import com.fdkankan.common.util.JwtUtil;
-import com.fdkankan.common.util.RandomUtil;
 import com.fdkankan.fyun.face.FYunFileServiceInterface;
 import com.fdkankan.image.MatrixToImageWriterUtil;
 import com.fdkankan.model.constants.ConstantFilePath;
@@ -116,6 +114,8 @@ public class SceneProServiceImpl extends ServiceImpl<ISceneProMapper, ScenePro>
 
     @Value("${queue.modeling.obj.modeling-pre}")
     private String queueObjModelingPre;
+    @Value("${oss.bucket}")
+    private String bucket;
 
     @Autowired
     private RabbitMqProducer mqProducer;
@@ -179,22 +179,28 @@ public class SceneProServiceImpl extends ServiceImpl<ISceneProMapper, ScenePro>
         LambdaQueryWrapper<ScenePro> wrapper = new LambdaQueryWrapper<>();
         LambdaQueryWrapper<ScenePlus> plusWr = new LambdaQueryWrapper<>();
         Long count = 0L;
-        if(payStatus == 1){ //解封,判断用户权益,用户会员权益无限容量
+        if(payStatus == 1){         //解封,判断用户权益,用户会员权益无限容量
             count = userIncrementService.getValidCountByCameraId(cameraId);
             wrapper.orderByAsc(ScenePro::getCreateTime);
             plusWr.orderByAsc(ScenePlus::getCreateTime);
+            wrapper.eq(ScenePro::getPayStatus,-2);
+            plusWr.eq(ScenePlus::getPayStatus,-2);
         }else {
             wrapper.orderByDesc(ScenePro::getCreateTime);
             plusWr.orderByDesc(ScenePlus::getCreateTime);
+            wrapper.eq(ScenePro::getPayStatus,1);
+            plusWr.eq(ScenePlus::getPayStatus,1);
         }
+
         wrapper.eq(ScenePro::getCameraId,cameraId)
-                .eq(ScenePro::getPayStatus,payStatus)
                 .eq(ScenePro::getSceneScheme,4)
                 .eq(ScenePro::getIsUpgrade,0);
-        plusWr.eq(ScenePlus::getCameraId,cameraId)
-                .eq(ScenePlus::getPayStatus,payStatus);
+
+        plusWr.eq(ScenePlus::getCameraId,cameraId);
+
         List<ScenePro> list = this.list(wrapper);
         List<ScenePlus> plusList = scenePlusService.list(plusWr);
+
         Long beyondSpace = Math.abs(cameraDetail.getUsedSpace() - cameraDetail.getTotalSpace());
         Long accumulateSpace = 0L;
         List<Long> lockedIds = new ArrayList<>();
@@ -406,12 +412,32 @@ public class SceneProServiceImpl extends ServiceImpl<ISceneProMapper, ScenePro>
             throw new BusinessException(CameraConstant.FAILURE_CODE_6029, CameraConstant.FAILURE_MSG_6029);
         }
         String newNum = scene3dNumService.generateSceneNum(detailEntity.getType());
+        String title = scenePro == null ? scenePlus.getTitle() : scenePro.getSceneName();
+        String newTitle = title.concat("(copy)");
+
+        Long sceneId = scenePro == null ? scenePlus.getId() :scenePro.getId();
+        Long newSceneId = null;
+        FolderScene folderScene = folderSceneService.getByType(sceneId, null);
+        String time = DateUtil.date2String(new Date(),DateUtil.YYYYMMDDHHMMSSSSS_DATA_FORMAT);
+
 
         if(scenePro !=null){        //v3场景复制
-            this.copyV3Scene(scenePro,newNum,detailEntity);
+            log.info("场景复制--V3--OldNum:{},oldTitle:{},newNum:{},newTitle:{}",
+                    scenePro.getNum(),scenePro.getSceneName(),newNum,newTitle);
+            scenePro.setSceneName(newTitle);
+            newSceneId = this.copyV3Scene(scenePro, newNum, detailEntity,time);
         }
         if(scenePlus != null){      //v4场景复制
-            scenePlusService.copyV4Scene(scenePlus,newNum,detailEntity);
+            log.info("场景复制--V4--OldNum:{},oldTitle:{},newNum:{},newTitle:{}",
+                    scenePlus.getNum(),scenePlus.getTitle(),newNum,newTitle);
+            scenePlus.setTitle(newTitle);
+            newSceneId =  scenePlusService.copyV4Scene(scenePlus,newNum,detailEntity,time);
+        }
+        log.info("场景复制--完成--sceneId:{}",newSceneId);
+        if(newSceneId != null && folderScene!= null){
+            folderScene.setId(null);
+            folderScene.setSceneId(newSceneId);
+            folderSceneService.save(folderScene);
         }
 
     }
@@ -430,7 +456,7 @@ public class SceneProServiceImpl extends ServiceImpl<ISceneProMapper, ScenePro>
 
 
     @Override
-    public void copyV3Scene(ScenePro oldScene,String newNum,CameraDetail cameraDetail) throws Exception {
+    public Long copyV3Scene(ScenePro oldScene,String newNum,CameraDetail cameraDetail,String time) throws Exception {
         SceneProEdit oldEditScene = sceneProEditService.getByProId(oldScene.getId());
 
         String oldNum = oldScene.getNum();
@@ -438,20 +464,38 @@ public class SceneProServiceImpl extends ServiceImpl<ISceneProMapper, ScenePro>
         oldScene.setId(null);
         oldScene.setStatus(0);
         oldScene.setNum(newNum);
-        oldScene.setSceneName(oldScene.getSceneName().concat("(copy)"));
         oldScene.setWebSite(oldScene.getWebSite().replace(oldScene.getNum(), newNum));
         oldScene.setThumb(oldScene.getThumb().replace(oldScene.getNum(), newNum));
-        oldScene.setVideos(oldScene.getVideos().replace(oldNum,newNum));
+        oldScene.setVideos(this.setVideos(oldScene.getVideos(),oldNum,newNum));
         oldScene.setViewCount(0);
         String preDataSource = oldScene.getDataSource();
-        oldScene.setDataSource(this.setDataSource(preDataSource,oldScene.getSceneSource()));
+        String newDataSource = this.setDataSource(preDataSource,time);
+        oldScene.setDataSource(newDataSource);
 
         this.save(oldScene);
+        //更新video
+        Map map = new HashMap();
+        JSONObject object = new JSONObject();
+        if(StringUtils.isNotEmpty(oldScene.getVideos())){
+            object = JSONObject.parseObject(oldScene.getVideos());
+            if(object.containsKey("upPath")){
+                String upPath = object.getString("upPath");
+                upPath = upPath.replace(oldNum,newNum);
+                object.put("upPath",upPath);
+            }
+            oldScene.setVideos(object.toJSONString());
+            log.info("更新 scene.json");
+            map.put("videos",oldScene.getVideos());
+        }
+        map.put("sceneName",oldScene.getSceneName());
+        map.put("webSite",oldScene.getWebSite());
+        map.put("thumb",oldScene.getThumb());
+        map.put("num",oldScene.getNum());
+        map.put("id",oldScene.getId());
+        map.put("dataSource",oldScene.getDataSource());
 
         sceneCopyLogService.saveByNum(oldNum,newNum,oldScene.getUserId());
         //复制完成更新相机容量
-        cameraDetail.setUsedSpace(cameraDetail.getUsedSpace() + oldScene.getSpace());
-        cameraDetailService.updateById(cameraDetail);
 
         oldEditScene.setId(null);
         oldEditScene.setProId(oldScene.getId());
@@ -467,14 +511,31 @@ public class SceneProServiceImpl extends ServiceImpl<ISceneProMapper, ScenePro>
         CompletableFuture.runAsync(() -> {
             try {
                 log.info("开始复制场景-{}", new Date());
-
+                String buildModelPath = ConstantFilePath.BUILD_MODEL_PATH;
+                if(oldScene.getSceneSource().equals(4)){
+                    buildModelPath = ConstantFilePath.BUILD_MODEL_LASER_PATH;
+                }
+                this.copyFdage(preDataSource,newDataSource,buildModelPath,time);
                 //oss复制计算结果资源
-                this.copyOssSource("v3",oldNum,newNum);
-                this.copyLocalSource(oldNum,newNum);
-
-                updateSceneJson("v3",oldScene.getVideos(),newNum,oldScene.getSceneName(),oldScene.getWebSite(),oldScene.getThumb(),oldScene.getId());
+                downloadFromOldNumFromOss(oldNum, newNum);
+                // 复制本地secen.json
+                copyOldSceneLocalToNew(oldNum, newNum);
+                FileUtils.writeJsonFile(ConstantFilePath.SCENE_PATH + "data/data" + newNum + File.separator + "scene.json", map);
                 //上传资源到oss
                 uploadNewSceneToOss(newNum);
+
+                FileUtils.delFolder(ConstantFilePath.SCENE_PATH + "images/images" + newNum);
+                FileUtils.delFolder(ConstantFilePath.SCENE_PATH + "data/data" + newNum);
+                FileUtils.delFolder(ConstantFilePath.SCENE_PATH + "voice/voice" + newNum);
+                FileUtils.delFolder(ConstantFilePath.SCENE_PATH + "video/video" + newNum);
+
+                FileUtils.copyDirectiory(ConstantFilePath.SCENE_PATH +"images/images" + oldNum,ConstantFilePath.SCENE_PATH +"images/images" + newNum);
+                FileUtils.copyDirectiory(ConstantFilePath.SCENE_PATH +"data/data" + oldNum,ConstantFilePath.SCENE_PATH +"data/data" + newNum);
+                FileUtils.writeJsonFile(ConstantFilePath.SCENE_PATH + "data/data" + newNum + File.separator + "scene.json", map);
+                reloadFile(ConstantFilePath.SCENE_PATH + "data/data" + newNum + "/link-scene.json",oldNum, newNum);
+                reloadFile(ConstantFilePath.SCENE_PATH + "data/data" + newNum + "/hot.json",oldNum, newNum);
+                FileUtils.copyDirectiory(ConstantFilePath.SCENE_PATH +"voice/voice" + oldNum,ConstantFilePath.SCENE_PATH +"voice/voice" + newNum);
+                FileUtils.copyDirectiory(ConstantFilePath.SCENE_PATH +"video/video" + oldNum,ConstantFilePath.SCENE_PATH +"video/video" + newNum);
                 oldScene.setStatus(-2);
                 this.updateById(oldScene);
                 log.info("复制场景结束-{}", new Date());
@@ -482,69 +543,83 @@ public class SceneProServiceImpl extends ServiceImpl<ISceneProMapper, ScenePro>
                 log.error("复制场景异常", e);
             }
         });
-
+        return oldScene.getId();
     }
 
-    @Override
-    public String setDataSource(String preDataSource,Integer sceneSource) throws Exception {
-        String datasourceFix;
-        String newDataSource;
-        // 判断场景是否拷贝过
-        ScenePro entity;
-        do{
-            datasourceFix = RandomUtil.generateShortUuid();
-            entity = this.findByFileId(preDataSource.concat(datasourceFix));
-        }while(!ObjectUtils.isEmpty(entity));
-        newDataSource =  datasourceFix.concat(datasourceFix);
-
-        //oss复制源文件
-        String buildModelPath = ConstantFilePath.BUILD_MODEL_PATH;
-        if(sceneSource.equals(4)){
-            buildModelPath = ConstantFilePath.BUILD_MODEL_LASER_PATH;
-        }
-        CreateObjUtil.ossUtilCp(ConstantFilePath.OSS_PREFIX +newDataSource.replace(buildModelPath, "")+"/", newDataSource);
-
-        List<String> urlList = new ArrayList<>();
-        FileUtils.readfilePath(newDataSource, urlList);
-        Map<String,String> fileMap = new HashMap<>();
-        for(String url : urlList){
-            fileMap.put(url, ConstantFilePath.OSS_PREFIX + url.replace(buildModelPath, ""));
-        }
-        fYunFileService.uploadMulFiles(fileMap);
+    /**
+     * 从旧场景下载资源
+     * @param sceneNum
+     * @param newNum
+     * @throws Exception
+     */
+    private void downloadFromOldNumFromOss(String sceneNum, String newNum) throws Exception {
+        CreateObjUtil.ossUtilCp("images/images" + sceneNum + "/", ConstantFilePath.SCENE_PATH + "images/images" + newNum);
+        CreateObjUtil.ossUtilCp("data/data" + sceneNum + "/", ConstantFilePath.SCENE_PATH + "data/data" + newNum);
+        CreateObjUtil.ossUtilCp("voice/voice" + sceneNum + "/", ConstantFilePath.SCENE_PATH + "voice/voice" + newNum);
+        CreateObjUtil.ossUtilCp("video/video" + sceneNum + "/", ConstantFilePath.SCENE_PATH + "video/video" + newNum);
+    }
 
-        FileUtils.delAllFile(newDataSource);
+    /**
+     * 从本地旧场景拷贝资源到新场景
+     * @param sceneNum
+     * @param newNum
+     */
+    private void copyOldSceneLocalToNew(String sceneNum, String newNum) throws Exception {
+        FileUtils.copyFolderAllFiles(ConstantFilePath.SCENE_PATH + "data/data" + sceneNum + "/",
+                ConstantFilePath.SCENE_PATH + "data/data" + newNum + "/", true);
 
-        FileUtils.copyFolderAllFiles(preDataSource+"/",newDataSource+"/", true);
-        return datasourceFix.concat(datasourceFix);
+        reloadFile(ConstantFilePath.SCENE_PATH + "data/data" + newNum + "/link-scene.json",sceneNum, newNum);
+        reloadFile(ConstantFilePath.SCENE_PATH + "data/data" + newNum + "/hot.json",sceneNum, newNum);
     }
 
-    @Override
-    public void copyOssSource(String type ,String sceneNum, String newNum) throws Exception {
-        List<String > copyList = new ArrayList<>();
-        if(type.equals("v3")){
-            copyList.add("images/images" + sceneNum);
-            copyList.add("data/data" + sceneNum);
-            copyList.add("voice/voice" + sceneNum);
-            copyList.add("video/video"+ sceneNum);
-        }else if(type.equals("v4")){
-            String oldEditPath = String.format(UploadFilePath.EDIT_PATH, sceneNum);
-            String oldViewPath = String.format(UploadFilePath.VIEW_PATH, sceneNum);
-            copyList.add(oldEditPath);
-            copyList.add(oldViewPath);
+    public void copyFdage(String oldDataSource,String newDataSource,String buildModelPath,String time) throws Exception {
+
+        CreateObjUtil.ossUtilCp(ConstantFilePath.OSS_PREFIX + oldDataSource.replace(buildModelPath, "")+"/", newDataSource);
+        // 修改data.fdage
+        String data = FileUtils.readFile(newDataSource + "/data.fdage");
+        JSONObject jsonObject = JSONObject.parseObject(data);
+        if(ObjectUtils.isEmpty(jsonObject)){
+            log.error("data.fdage文件不存在");
+            throw new BusinessException(-1,"拷贝场景出错,data.fdage文件不存在");
         }
-        for (String sourcePath : copyList) {
-            fYunFileService.copyFileInBucket(sourcePath,sourcePath.replaceAll(sceneNum,newNum));
+        jsonObject.put("uuidtime",time);
+        FileUtils.writeFile(newDataSource + "/data.fdage", jsonObject.toJSONString());
+        CreateObjUtil.ossUtilCpFolder(newDataSource, bucket.concat("/" + ConstantFilePath.OSS_PREFIX + newDataSource.replace(buildModelPath, "")));
+
+        // 复制计算结果
+        CreateObjUtil.ossUtilCp(ConstantFilePath.OSS_PREFIX + oldDataSource.concat("_results/").replace(buildModelPath, ""), newDataSource.concat("_results"));
+        if(new File(newDataSource.concat("_results")).exists()){
+            CreateObjUtil.ossUtilCpFolder(newDataSource.concat("_results"),bucket.concat("/" + ConstantFilePath.OSS_PREFIX + newDataSource.concat("_results").replace(buildModelPath, "")));
+            FileUtils.delAllFile(newDataSource.concat("_results"));
         }
+        FileUtils.delAllFile(newDataSource);
+
+
+        FileUtils.copyFolderAllFiles(oldDataSource+"/",newDataSource+"/", true);
+
+    }
+    @Override
+    public String setDataSource(String preDataSource,String time) throws Exception {
+        SnowflakeIdGenerator snowflakeIdGenerator = new SnowflakeIdGenerator(0,1);
+        String[] datasource = preDataSource.split("/");
+        datasource[4] = snowflakeIdGenerator.nextId()+"";
+        datasource[5] = datasource[5].split("_")[0] + "_" + time;
+        return Arrays.stream(datasource).collect(Collectors.joining("/"));
     }
 
     @Override
-    public void copyLocalSource(String sceneNum, String newNum) throws Exception {
-        FileUtils.copyDirectiory(ConstantFilePath.SCENE_PATH +"images/images" + sceneNum,ConstantFilePath.SCENE_PATH +"images/images" + newNum);
-        FileUtils.copyDirectiory(ConstantFilePath.SCENE_PATH +"data/data" + sceneNum,ConstantFilePath.SCENE_PATH +"data/data" + newNum);
-        reloadFile(ConstantFilePath.SCENE_PATH + "data/data" + newNum + "/link-scene.json",sceneNum, newNum);
-        reloadFile(ConstantFilePath.SCENE_PATH + "data/data" + newNum + "/hot.json",sceneNum, newNum);
-        FileUtils.copyDirectiory(ConstantFilePath.SCENE_PATH +"voice/voice" + sceneNum,ConstantFilePath.SCENE_PATH +"voice/voice" + newNum);
-        FileUtils.copyDirectiory(ConstantFilePath.SCENE_PATH +"video/video" + sceneNum,ConstantFilePath.SCENE_PATH +"video/video" + newNum);
+    public String setVideos(String videos,String oldNum,String newNum) {
+        JSONObject object = new JSONObject();
+        if(StringUtils.isNotEmpty(videos)){
+            object = JSONObject.parseObject(videos);
+            if(object.containsKey("upPath")){
+                String upPath = object.getString("upPath");
+                upPath = upPath.replace(oldNum,newNum);
+                object.put("upPath",upPath);
+            }
+            log.info("更新 scene.json");
+        }
+        return object.toJSONString();
     }
 
     private void reloadFile(String filePath,String sceneNum, String newNum) throws Exception {
@@ -562,39 +637,10 @@ public class SceneProServiceImpl extends ServiceImpl<ISceneProMapper, ScenePro>
      * @param newNum
      */
     private void uploadNewSceneToOss(String newNum) {
-        Map<String, String> map = new HashMap();
-        List<String> urlList = new ArrayList<>();
-        FileUtils.readfilePath(ConstantFilePath.SCENE_PATH + "images/images" + newNum, urlList);
-        FileUtils.readfilePath(ConstantFilePath.SCENE_PATH + "data/data" + newNum, urlList);
-        FileUtils.readfilePath(ConstantFilePath.SCENE_PATH + "voice/voice" + newNum, urlList);
-        FileUtils.readfilePath(ConstantFilePath.SCENE_PATH + "video/video" + newNum, urlList);
-        for(String url : urlList){
-            map.put(url, url.replace(ConstantFilePath.SCENE_PATH, ""));
-        }
-        fYunFileService.uploadMulFiles(map);
-    }
-
-    @Override
-    public void updateSceneJson(String type,String videos,String newNum,String sceneName,String webSite,String thumb,Long id) throws Exception {
-        //更新video
-        HashMap<String,Object> map = new HashMap<>();
-        map.put("videos",videos);
-        map.put("sceneName",sceneName);
-        map.put("webSite",webSite);
-        map.put("thumb",thumb);
-        map.put("num",newNum);
-        map.put("id",id);
-        String uploadPath ;
-        String localPath = ConstantFilePath.SCENE_PATH + "data/data" + newNum + File.separator + "scene.json";
-        if(type.equals("v3")){
-            uploadPath = localPath.replace(ConstantFilePath.SCENE_PATH, "");
-        }else {
-            uploadPath =localPath.replace(ConstantFilePath.SCENE_V4_PATH, "");
-        }
-        FileUtils.writeJsonFile(localPath, map);
-        if(type.equals("v4")){
-            fYunFileService.uploadFile(localPath,uploadPath);
-        }
+        CreateObjUtil.ossUtilCpFolder("/mnt/4Dkankan/scene/images/images" + newNum, bucket.concat("/images/images") + newNum);
+        CreateObjUtil.ossUtilCpFolder("/mnt/4Dkankan/scene/data/data" + newNum, bucket.concat("/data/data") + newNum);
+        CreateObjUtil.ossUtilCpFolder("/mnt/4Dkankan/scene/voice/voice" + newNum, bucket.concat("/voice/voice") + newNum);
+        CreateObjUtil.ossUtilCpFolder("/mnt/4Dkankan/scene/video/video" + newNum, bucket.concat("/video/video") + newNum);
     }
 
     @Override

+ 70 - 0
src/main/java/com/fdkankan/ucenter/vo/SceneEditControlsVO.java

@@ -0,0 +1,70 @@
+package com.fdkankan.ucenter.vo;
+
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import java.io.Serializable;
+
+/**
+ * <p>
+ * TODO
+ * </p>
+ *
+ * @author dengsixing
+ * @since 2022/1/18
+ **/
+@Data
+@Builder
+@NoArgsConstructor
+@AllArgsConstructor
+public class SceneEditControlsVO implements Serializable {
+
+    /**
+     * 是否展示小地图(0-不展示,1-展示)
+     */
+    private Integer showMap;
+
+    /**
+     * 是否需要密码(0-不需要,1-需要)
+     */
+    private Integer showLock;
+
+    /**
+     * 是否展示标题(0-不需要,1-需要)
+     */
+    private Integer showTitle;
+
+    /**
+     * 是否展示漫游按钮(0-不需要,1-需要)
+     */
+    private Integer showPanorama;
+
+    /**
+     * 是否展示3D按钮(0-不需要,1-需要)
+     */
+    private Integer showDollhouse;
+
+    /**
+     * 是否展示2D按钮(0-不需要,1-需要)
+     */
+    private Integer showFloorplan;
+
+    /**
+     * 是否展示VR(0-不需要,1-需要)
+     */
+    private Integer showVR;
+
+    /**
+     * 是否展示自动导览(0-不需要,1-需要)
+     */
+    private Integer showTour;
+
+    /**
+     * 是否展示测量线(0-不需要,1-需要)
+     */
+    private Integer showRule;
+
+
+}

+ 4 - 1
src/main/resources/mapper/ucenter/FolderSceneMapper.xml

@@ -4,7 +4,10 @@
 
     <select id="getByType" resultType="com.fdkankan.ucenter.entity.FolderScene">
         SELECT b.* from t_folder a left join t_folder_scene b on a.id = b.folder_id
-        where  b.rec_status ='A' and b.scene_id = #{sceneId} and a.type = #{type}
+        where  b.rec_status ='A' and b.scene_id = #{sceneId}
+        <if test= 'type != null'>
+         and a.type = #{type}
+        </if>
         limit 1
     </select>
     <select id="getGroupByFolderIds" resultType="com.fdkankan.ucenter.vo.response.GroupByCount">