lyhzzz 2 år sedan
förälder
incheckning
884c675dcd
31 ändrade filer med 1199 tillägg och 10 borttagningar
  1. 5 0
      pom.xml
  2. 0 1
      src/main/java/com/fdkankan/manage_jp/common/RedisKeyUtil.java
  3. 1 0
      src/main/java/com/fdkankan/manage_jp/common/ResultCode.java
  4. 21 0
      src/main/java/com/fdkankan/manage_jp/controller/SceneEditControlsController.java
  5. 21 0
      src/main/java/com/fdkankan/manage_jp/controller/SceneEditInfoExtController.java
  6. 33 4
      src/main/java/com/fdkankan/manage_jp/controller/SceneProController.java
  7. 59 0
      src/main/java/com/fdkankan/manage_jp/entity/Scene3dNum.java
  8. 114 0
      src/main/java/com/fdkankan/manage_jp/entity/SceneEditControls.java
  9. 132 0
      src/main/java/com/fdkankan/manage_jp/entity/SceneEditInfoExt.java
  10. 2 2
      src/main/java/com/fdkankan/manage_jp/generate/AutoGenerate.java
  11. 18 0
      src/main/java/com/fdkankan/manage_jp/mapper/IScene3dNumMapper.java
  12. 18 0
      src/main/java/com/fdkankan/manage_jp/mapper/ISceneEditControlsMapper.java
  13. 18 0
      src/main/java/com/fdkankan/manage_jp/mapper/ISceneEditInfoExtMapper.java
  14. 17 0
      src/main/java/com/fdkankan/manage_jp/service/IScene3dNumService.java
  15. 17 0
      src/main/java/com/fdkankan/manage_jp/service/ISceneEditControlsService.java
  16. 17 0
      src/main/java/com/fdkankan/manage_jp/service/ISceneEditInfoExtService.java
  17. 2 0
      src/main/java/com/fdkankan/manage_jp/service/IScenePlusService.java
  18. 2 0
      src/main/java/com/fdkankan/manage_jp/service/ISceneProService.java
  19. 51 0
      src/main/java/com/fdkankan/manage_jp/service/impl/Scene3dNumServiceImpl.java
  20. 129 0
      src/main/java/com/fdkankan/manage_jp/service/impl/SceneCommonService.java
  21. 26 0
      src/main/java/com/fdkankan/manage_jp/service/impl/SceneEditControlsServiceImpl.java
  22. 25 0
      src/main/java/com/fdkankan/manage_jp/service/impl/SceneEditInfoExtServiceImpl.java
  23. 142 2
      src/main/java/com/fdkankan/manage_jp/service/impl/ScenePlusServiceImpl.java
  24. 108 1
      src/main/java/com/fdkankan/manage_jp/service/impl/SceneProServiceImpl.java
  25. 21 0
      src/main/java/com/fdkankan/manage_jp/util/FileUtil.java
  26. 20 0
      src/main/java/com/fdkankan/manage_jp/util/GenerateNumUtil.java
  27. 28 0
      src/main/java/com/fdkankan/manage_jp/util/SceneResourcePath.java
  28. 137 0
      src/main/java/com/fdkankan/manage_jp/util/SnowflakeIdGenerator.java
  29. 5 0
      src/main/resources/mapper/manage_jp/Scene3dNumMapper.xml
  30. 5 0
      src/main/resources/mapper/manage_jp/SceneEditControlsMapper.xml
  31. 5 0
      src/main/resources/mapper/manage_jp/SceneEditInfoExtMapper.xml

+ 5 - 0
pom.xml

@@ -40,6 +40,11 @@
             <artifactId>4dkankan-utils-redis</artifactId>
             <version>3.0.0-SNAPSHOT</version>
         </dependency>
+        <dependency>
+            <groupId>com.fdkankan</groupId>
+            <artifactId>4dkankan-utils-image</artifactId>
+            <version>3.0.0-SNAPSHOT</version>
+        </dependency>
 
 
         <dependency>

+ 0 - 1
src/main/java/com/fdkankan/manage_jp/common/RedisKeyUtil.java

@@ -9,5 +9,4 @@ public class RedisKeyUtil {
 
     public static final String loginToken= "manage:login:token:%s";
 
-
 }

+ 1 - 0
src/main/java/com/fdkankan/manage_jp/common/ResultCode.java

@@ -23,6 +23,7 @@ public enum ResultCode  {
     MAIL_TEMPLATE_ERROR(50006, "邮件发送模板不存在"),
     MAIL_SEND_ERROR(50007, "邮件发送失败"),
     CAMERA_IN(50008, "相机已存在"),
+    SCENE_ERROR(50009, "场景状态不对"),
 
 
     ;

+ 21 - 0
src/main/java/com/fdkankan/manage_jp/controller/SceneEditControlsController.java

@@ -0,0 +1,21 @@
+package com.fdkankan.manage_jp.controller;
+
+
+import org.springframework.web.bind.annotation.RequestMapping;
+
+import org.springframework.web.bind.annotation.RestController;
+
+/**
+ * <p>
+ *  前端控制器
+ * </p>
+ *
+ * @author 
+ * @since 2023-04-23
+ */
+@RestController
+@RequestMapping("/manage_jp/sceneEditControls")
+public class SceneEditControlsController {
+
+}
+

+ 21 - 0
src/main/java/com/fdkankan/manage_jp/controller/SceneEditInfoExtController.java

@@ -0,0 +1,21 @@
+package com.fdkankan.manage_jp.controller;
+
+
+import org.springframework.web.bind.annotation.RequestMapping;
+
+import org.springframework.web.bind.annotation.RestController;
+
+/**
+ * <p>
+ *  前端控制器
+ * </p>
+ *
+ * @author 
+ * @since 2023-04-23
+ */
+@RestController
+@RequestMapping("/manage_jp/sceneEditInfoExt")
+public class SceneEditInfoExtController {
+
+}
+

+ 33 - 4
src/main/java/com/fdkankan/manage_jp/controller/SceneProController.java

@@ -1,16 +1,19 @@
 package com.fdkankan.manage_jp.controller;
 
 
+import com.alibaba.fastjson.JSONObject;
 import com.fdkankan.common.util.JwtUtil;
 import com.fdkankan.manage_jp.common.Result;
+import com.fdkankan.manage_jp.common.ResultCode;
+import com.fdkankan.manage_jp.entity.ScenePlus;
+import com.fdkankan.manage_jp.entity.ScenePro;
 import com.fdkankan.manage_jp.entity.User;
 import com.fdkankan.manage_jp.entity.UserRole;
+import com.fdkankan.manage_jp.exception.BusinessException;
 import com.fdkankan.manage_jp.httpClient.client.FdKKClient;
-import com.fdkankan.manage_jp.service.IDownService;
-import com.fdkankan.manage_jp.service.ISceneProService;
-import com.fdkankan.manage_jp.service.IUserRoleService;
-import com.fdkankan.manage_jp.service.IUserService;
+import com.fdkankan.manage_jp.service.*;
 import com.fdkankan.manage_jp.vo.request.SceneParam;
+import org.apache.commons.lang3.StringUtils;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.web.bind.annotation.*;
 
@@ -35,6 +38,8 @@ public class SceneProController extends BaseController{
     @Autowired
     ISceneProService sceneProService;
     @Autowired
+    IScenePlusService scenePlusService;
+    @Autowired
     IUserService userService;
     @Autowired
     IUserRoleService userRoleService;
@@ -77,5 +82,29 @@ public class SceneProController extends BaseController{
         return Result.success(fdKKClient.upgradeToV4(map));
     }
 
+
+    /**
+     * 复制场景
+     */
+    @PostMapping("/copyScene")
+    @ResponseBody
+    public Result copyScene(@RequestBody JSONObject param){
+        String num = param.getString("num");
+        if(StringUtils.isBlank(num)){
+            throw new BusinessException(ResultCode.PARAM_ERROR);
+        }
+        ScenePro scenePro = sceneProService.getByNum(num);
+        if(scenePro !=null){
+            sceneProService.copyScene(scenePro);
+        }
+        ScenePlus scenePlus = scenePlusService.getByNum(num);
+        if(scenePro !=null){
+            scenePlusService.copyScene(scenePlus);
+        }
+        if(scenePro == null && scenePlus == null){
+            throw new BusinessException(ResultCode.NOT_RECORD);
+        }
+        return Result.success();
+    }
 }
 

+ 59 - 0
src/main/java/com/fdkankan/manage_jp/entity/Scene3dNum.java

@@ -0,0 +1,59 @@
+package com.fdkankan.manage_jp.entity;
+
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableLogic;
+import com.baomidou.mybatisplus.annotation.TableName;
+import java.io.Serializable;
+import java.util.Date;
+import lombok.Getter;
+import lombok.Setter;
+
+/**
+ * <p>
+ * 场景编码表
+ * </p>
+ *
+ * @author 
+ * @since 2023-04-21
+ */
+@Getter
+@Setter
+@TableName("t_scene_3d_num")
+public class Scene3dNum implements Serializable {
+
+    private static final long serialVersionUID = 1L;
+
+    @TableId(value = "id", type = IdType.AUTO)
+    private Long id;
+
+    @TableField("used")
+    private Integer used;
+
+    @TableField("folder_name")
+    private String folderName;
+
+    @TableField("code")
+    private String code;
+
+    /**
+     * 记录的状态,A: 生效,I: 禁用
+     */
+    @TableField("rec_status")
+    private String recStatus;
+
+    /**
+     * 更新时间
+     */
+    @TableField("update_time")
+    private Date updateTime;
+
+    /**
+     * 创建时间
+     */
+    @TableField("create_time")
+    private Date createTime;
+
+
+}

+ 114 - 0
src/main/java/com/fdkankan/manage_jp/entity/SceneEditControls.java

@@ -0,0 +1,114 @@
+package com.fdkankan.manage_jp.entity;
+
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableLogic;
+import com.baomidou.mybatisplus.annotation.TableName;
+import java.io.Serializable;
+import java.util.Date;
+import lombok.Getter;
+import lombok.Setter;
+
+/**
+ * <p>
+ * 
+ * </p>
+ *
+ * @author 
+ * @since 2023-04-23
+ */
+@Getter
+@Setter
+@TableName("t_scene_edit_controls")
+public class SceneEditControls implements Serializable {
+
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * 主键
+     */
+    @TableId(value = "id", type = IdType.AUTO)
+    private Long id;
+
+    /**
+     * t_scene_edit_info表id
+     */
+    @TableField("edit_info_id")
+    private Long editInfoId;
+
+    /**
+     * 是否展示小地图(0-不展示,1-展示)
+     */
+    @TableField("show_map")
+    private Integer showMap;
+
+    /**
+     * 是否需要密码(0-不需要,1-需要)
+     */
+    @TableField("show_lock")
+    private Integer showLock;
+
+    /**
+     * 是否展示标题(0-不需要,1-需要)
+     */
+    @TableField("show_title")
+    private Integer showTitle;
+
+    /**
+     * 是否展示漫游按钮(0-不需要,1-需要)
+     */
+    @TableField("show_panorama")
+    private Integer showPanorama;
+
+    /**
+     * 是否展示3D按钮(0-不需要,1-需要)
+     */
+    @TableField("show_dollhouse")
+    private Integer showDollhouse;
+
+    /**
+     * 是否展示2D按钮(0-不需要,1-需要)
+     */
+    @TableField("show_floorplan")
+    private Integer showFloorplan;
+
+    /**
+     * 是否展示VR(0-不需要,1-需要)
+     */
+    @TableField("show_VR")
+    private Integer showVr;
+
+    /**
+     * 是否展示自动导览(0-不需要,1-需要)
+     */
+    @TableField("show_tour")
+    private Integer showTour;
+
+    /**
+     * 是否展示测量线(0-不需要,1-需要)
+     */
+    @TableField("show_rule")
+    private Integer showRule;
+
+    /**
+     * 创建时间
+     */
+    @TableField("create_time")
+    private Date createTime;
+
+    /**
+     * 更新时间
+     */
+    @TableField("update_time")
+    private Date updateTime;
+
+    /**
+     * A-有效,I-无效
+     */
+    @TableField("rec_status")
+    @TableLogic(value = "A",delval = "I")
+    private String recStatus;
+
+
+}

+ 132 - 0
src/main/java/com/fdkankan/manage_jp/entity/SceneEditInfoExt.java

@@ -0,0 +1,132 @@
+package com.fdkankan.manage_jp.entity;
+
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableLogic;
+import com.baomidou.mybatisplus.annotation.TableName;
+import java.io.Serializable;
+import java.util.Date;
+import lombok.Getter;
+import lombok.Setter;
+
+/**
+ * <p>
+ * 
+ * </p>
+ *
+ * @author 
+ * @since 2023-04-23
+ */
+@Getter
+@Setter
+@TableName("t_scene_edit_info_ext")
+public class SceneEditInfoExt implements Serializable {
+
+    private static final long serialVersionUID = 1L;
+
+    @TableId(value = "id", type = IdType.AUTO)
+    private Long id;
+
+    @TableField("scene_pro_id")
+    private Long sceneProId;
+
+    @TableField("scene_plus_id")
+    private Long scenePlusId;
+
+    @TableField("edit_info_id")
+    private Long editInfoId;
+
+    /**
+     * 户型角度
+     */
+    @TableField("floor_plan_angle")
+    private Float floorPlanAngle;
+
+    /**
+     * 指南针角度
+     */
+    @TableField("floor_plan_compass")
+    private Float floorPlanCompass;
+
+    /**
+     * 大场景序号(随心装场景码)  原pro_edit表中的字段
+     */
+    @TableField("vr_num")
+    private String vrNum;
+
+    /**
+     * 是否有保存导览(0-否,1-是)
+     */
+    @TableField("tours")
+    private Integer tours;
+
+    /**
+     * 马赛克数据
+     */
+    @TableField("mosaics")
+    private String mosaics;
+
+    /**
+     * 是否有马赛克
+     */
+    @TableField("mosaic")
+    private Integer mosaic;
+
+    /**
+     * 水印文件名
+     */
+    @TableField("water_mark")
+    private String waterMark;
+
+    /**
+     * 是否有场景关联(0-否,1-是)
+     */
+    @TableField("links")
+    private Integer links;
+
+    /**
+     * 是否有滤镜(0-否,1-是)
+     */
+    @TableField("filters")
+    private Integer filters;
+
+    /**
+     * 风格滤镜数据
+     */
+    @TableField("roi_filter")
+    private String roiFilter;
+
+    /**
+     * 是否有监控摄像头(0-否,1-是)
+     */
+    @TableField("surveillances")
+    private Integer surveillances;
+
+    /**
+     * 二维码logo路径(oss相对路径)
+     */
+    @TableField("share_logo_img")
+    private String shareLogoImg;
+
+    /**
+     * 创建时间
+     */
+    @TableField("create_time")
+    private Date createTime;
+
+    /**
+     * 修改时间
+     */
+    @TableField("update_time")
+    private Date updateTime;
+
+    /**
+     * A-有效,I-无效
+     */
+    @TableField("rec_status")
+    @TableLogic(value = "A",delval = "I")
+    private String recStatus;
+
+
+}

+ 2 - 2
src/main/java/com/fdkankan/manage_jp/generate/AutoGenerate.java

@@ -18,7 +18,7 @@ public class AutoGenerate {
         String path =System.getProperty("user.dir");
 
         generate(path,"manage_jp", getTables(new String[]{
-              "t_mail_template"
+              "t_scene_edit_controls"
         }));
 
 //        generate(path,"goods", getTables(new String[]{
@@ -46,7 +46,7 @@ public class AutoGenerate {
 
 
     public static void  generate(String path,String moduleName,  List<String> tables){
-        FastAutoGenerator.create("jdbc:mysql://120.77.76.141:13306/4dkankan_v4",
+        FastAutoGenerator.create("jdbc:mysql://47.106.180.58:13306/4dkankan_v4",
                 "root","JK20220120%JIK")
                 .globalConfig(builder -> {
                     builder.author("")               //作者

+ 18 - 0
src/main/java/com/fdkankan/manage_jp/mapper/IScene3dNumMapper.java

@@ -0,0 +1,18 @@
+package com.fdkankan.manage_jp.mapper;
+
+import com.fdkankan.manage_jp.entity.Scene3dNum;
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import org.apache.ibatis.annotations.Mapper;
+
+/**
+ * <p>
+ * 场景编码表 Mapper 接口
+ * </p>
+ *
+ * @author 
+ * @since 2023-04-21
+ */
+@Mapper
+public interface IScene3dNumMapper extends BaseMapper<Scene3dNum> {
+
+}

+ 18 - 0
src/main/java/com/fdkankan/manage_jp/mapper/ISceneEditControlsMapper.java

@@ -0,0 +1,18 @@
+package com.fdkankan.manage_jp.mapper;
+
+import com.fdkankan.manage_jp.entity.SceneEditControls;
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import org.apache.ibatis.annotations.Mapper;
+
+/**
+ * <p>
+ *  Mapper 接口
+ * </p>
+ *
+ * @author 
+ * @since 2023-04-23
+ */
+@Mapper
+public interface ISceneEditControlsMapper extends BaseMapper<SceneEditControls> {
+
+}

+ 18 - 0
src/main/java/com/fdkankan/manage_jp/mapper/ISceneEditInfoExtMapper.java

@@ -0,0 +1,18 @@
+package com.fdkankan.manage_jp.mapper;
+
+import com.fdkankan.manage_jp.entity.SceneEditInfoExt;
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import org.apache.ibatis.annotations.Mapper;
+
+/**
+ * <p>
+ *  Mapper 接口
+ * </p>
+ *
+ * @author 
+ * @since 2023-04-23
+ */
+@Mapper
+public interface ISceneEditInfoExtMapper extends BaseMapper<SceneEditInfoExt> {
+
+}

+ 17 - 0
src/main/java/com/fdkankan/manage_jp/service/IScene3dNumService.java

@@ -0,0 +1,17 @@
+package com.fdkankan.manage_jp.service;
+
+import com.fdkankan.manage_jp.entity.Scene3dNum;
+import com.baomidou.mybatisplus.extension.service.IService;
+
+/**
+ * <p>
+ * 场景编码表 服务类
+ * </p>
+ *
+ * @author 
+ * @since 2023-04-21
+ */
+public interface IScene3dNumService extends IService<Scene3dNum> {
+
+    String generateNum();
+}

+ 17 - 0
src/main/java/com/fdkankan/manage_jp/service/ISceneEditControlsService.java

@@ -0,0 +1,17 @@
+package com.fdkankan.manage_jp.service;
+
+import com.fdkankan.manage_jp.entity.SceneEditControls;
+import com.baomidou.mybatisplus.extension.service.IService;
+
+/**
+ * <p>
+ *  服务类
+ * </p>
+ *
+ * @author 
+ * @since 2023-04-23
+ */
+public interface ISceneEditControlsService extends IService<SceneEditControls> {
+
+    SceneEditControls getBySceneEditId(Long sceneEditInfoId);
+}

+ 17 - 0
src/main/java/com/fdkankan/manage_jp/service/ISceneEditInfoExtService.java

@@ -0,0 +1,17 @@
+package com.fdkankan.manage_jp.service;
+
+import com.fdkankan.manage_jp.entity.SceneEditInfoExt;
+import com.baomidou.mybatisplus.extension.service.IService;
+
+/**
+ * <p>
+ *  服务类
+ * </p>
+ *
+ * @author 
+ * @since 2023-04-23
+ */
+public interface ISceneEditInfoExtService extends IService<SceneEditInfoExt> {
+
+    SceneEditInfoExt getByEditInfoId(Long sceneEditInfoId);
+}

+ 2 - 0
src/main/java/com/fdkankan/manage_jp/service/IScenePlusService.java

@@ -16,4 +16,6 @@ public interface IScenePlusService extends IService<ScenePlus> {
     ScenePlus getByNum(String sceneNum);
 
     void unbind(Long cameraId);
+
+    void copyScene(ScenePlus scenePlus);
 }

+ 2 - 0
src/main/java/com/fdkankan/manage_jp/service/ISceneProService.java

@@ -29,4 +29,6 @@ public interface ISceneProService extends IService<ScenePro> {
     void deleteByNum(String sceneNum);
 
     void unbind(Long cameraId);
+
+    void copyScene(ScenePro scenePro);
 }

+ 51 - 0
src/main/java/com/fdkankan/manage_jp/service/impl/Scene3dNumServiceImpl.java

@@ -0,0 +1,51 @@
+package com.fdkankan.manage_jp.service.impl;
+import java.util.Date;
+
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.fdkankan.manage_jp.entity.Scene3dNum;
+import com.fdkankan.manage_jp.mapper.IScene3dNumMapper;
+import com.fdkankan.manage_jp.service.IScene3dNumService;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.fdkankan.manage_jp.util.GenerateNumUtil;
+import org.springframework.stereotype.Service;
+
+import java.sql.SQLOutput;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * <p>
+ * 场景编码表 服务实现类
+ * </p>
+ *
+ * @author 
+ * @since 2023-04-21
+ */
+@Service
+public class Scene3dNumServiceImpl extends ServiceImpl<IScene3dNumMapper, Scene3dNum> implements IScene3dNumService {
+
+    @Override
+    public String generateNum() {
+        String num = GenerateNumUtil.generateNum();
+        List<Scene3dNum> numList = this.getByNum(num);
+        if(numList.size() >0){
+            return this.generateNum();
+        }
+        Scene3dNum scene3dNum = new Scene3dNum();
+        scene3dNum.setUsed(1);
+        scene3dNum.setFolderName(null);
+        scene3dNum.setCode(num);
+        scene3dNum.setRecStatus("A");
+        scene3dNum.setUpdateTime(new Date());
+        scene3dNum.setCreateTime(new Date());
+        this.save(scene3dNum);
+        return num;
+    }
+
+    private List<Scene3dNum> getByNum(String num) {
+        LambdaQueryWrapper<Scene3dNum> wrapper = new LambdaQueryWrapper<>();
+        wrapper.eq(Scene3dNum::getCode,num);
+        return this.list(wrapper);
+    }
+
+}

+ 129 - 0
src/main/java/com/fdkankan/manage_jp/service/impl/SceneCommonService.java

@@ -0,0 +1,129 @@
+package com.fdkankan.manage_jp.service.impl;
+
+import cn.hutool.core.io.FileUtil;
+import com.alibaba.fastjson.JSON;
+import com.fdkankan.fyun.face.FYunFileServiceInterface;
+import com.fdkankan.image.MatrixToImageWriterUtil;
+import com.fdkankan.manage_jp.exception.BusinessException;
+import com.fdkankan.manage_jp.util.SceneResourcePath;
+import com.fdkankan.manage_jp.util.SnowflakeIdGenerator;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import java.io.File;
+import java.util.Date;
+
+@Service
+@Slf4j
+public class SceneCommonService {
+
+    @Autowired
+    FYunFileServiceInterface fYunFileServiceInterface;
+
+    /**
+     * 生成新的dataSouce
+     */
+    public String getNewDataSource(String oldDataSource){
+        String newDataSource = null;
+        if(StringUtils.isBlank(oldDataSource)){
+            throw new BusinessException(-1,"场景资源文件缺失,无法复制");
+        }
+        File oldDataSouceFile = new File(oldDataSource);
+        if(!oldDataSouceFile.exists()){
+            throw new BusinessException(-1,"场景资源文件缺失,无法复制");
+        }
+        if(!oldDataSource.contains("/")){
+            throw new BusinessException(-1,"场景dataSource格式错误");
+        }
+
+        String time = com.fdkankan.common.util.DateUtil.date2String(new Date(), com.fdkankan.common.util.DateUtil.YYYYMMDDHHMMSSSSS_DATA_FORMAT);
+        String[] split = oldDataSource.split("/");
+        if(split.length == 7 ){
+            String oldFileId = split[5];
+            Long fileId = SnowflakeIdGenerator.snowflakeIdGenerator.nextId();
+            newDataSource = oldDataSource.replace(oldFileId,fileId.toString());
+
+            String snCodeTime = split[6];
+            if(!snCodeTime.contains("_") || snCodeTime.split("_").length <= 1){
+                throw new BusinessException(-1,"场景dataSource格式错误");
+            }
+            newDataSource = newDataSource.replace(snCodeTime.split("_")[1],time);
+        }
+        if(newDataSource == null){
+            throw new BusinessException(-1,"场景dataSource格式错误");
+        }
+        return newDataSource;
+    }
+
+  public  void createNewQrCode(String newNum, String webSite){
+        try {
+            String outPathZh = SceneResourcePath.qrCodeBasePath + newNum + ".png";
+            String outPathEn = SceneResourcePath.qrCodeBasePath + newNum + "_en.png";
+            MatrixToImageWriterUtil.createQRCode(webSite, outPathZh, false,null);
+            MatrixToImageWriterUtil.createQRCode(webSite + "&lang=en", outPathEn, false, null);
+
+            fYunFileServiceInterface.uploadFile(outPathZh, String.format(SceneResourcePath.DOWNLOADS_QRCODE, newNum) + newNum + ".png");
+            fYunFileServiceInterface.uploadFile(outPathEn, String.format(SceneResourcePath.DOWNLOADS_QRCODE, newNum) + newNum + "_en.png");
+        }catch (Exception e){
+            log.info("copy-scene-error:{},newNum:{},error:{}",newNum,e);
+        }
+
+    }
+
+
+    public void updateNasSceneJson(String targetPath, String oldNum, String newNum,String oldSceneName,String newSceneName,String sceneVersion) {
+        String localPath = SceneResourcePath.nasBasePath + targetPath + "/" + "scene.json";
+        File file = new File(localPath);
+        if(!file.exists()){
+            log.error("sceneCopy-error--localFileExist:localPath:{},oldNum:{},newNum:{}",localPath,oldNum,newNum);
+            return;
+        }
+        String fileContent = cn.hutool.core.io.FileUtil.readUtf8String(file);
+        if(StringUtils.isNotBlank(fileContent)){
+            String newJson = fileContent.replaceAll(oldNum,newNum);
+            newJson = newJson.replaceAll(oldSceneName,newSceneName);
+            try {
+                com.fdkankan.manage_jp.util.FileUtil.writeFile(localPath,newJson);
+
+            }catch (Exception e){
+                log.error("writeFile-error:{}",e);
+            }
+        }
+        if("v3".equals(sceneVersion)){
+            String sceneJsonPath = String.format(SceneResourcePath.dataPath+"/scene.json", newNum);
+            fYunFileServiceInterface.uploadFile(localPath, sceneJsonPath);
+        }
+        if("v4".equals(sceneVersion)){
+            String sceneJsonPath = String.format(SceneResourcePath.DATA_VIEW_PATH+"scene.json", newNum);
+            fYunFileServiceInterface.uploadFile(localPath, sceneJsonPath);
+        }
+
+    }
+
+    public void updateOssJson(String targetPath,String oldNum, String newNum,String sceneVersion) {
+        String ossStatusJsonPath =  targetPath + "/" + "status.json";
+
+        if(!fYunFileServiceInterface.fileExist(ossStatusJsonPath)){
+            log.error("sceneCopy-error--ossFileExist:targetPath:{},oldNum:{},newNum:{}",ossStatusJsonPath,oldNum,newNum);
+            return;
+        }
+        String localPath = SceneResourcePath.nasBasePath + ossStatusJsonPath;
+        File file = new File(localPath);
+        if(!file.getParentFile().exists()){
+            file.mkdirs();
+        }
+        String fileContent = fYunFileServiceInterface.getFileContent(ossStatusJsonPath);
+        if(StringUtils.isNotBlank(fileContent)){
+            String newJson = fileContent.replaceAll(oldNum,newNum);
+            try {
+                com.fdkankan.manage_jp.util.FileUtil.writeFile(localPath,newJson);
+                fYunFileServiceInterface.uploadFile(localPath,ossStatusJsonPath);
+            }catch (Exception e){
+                log.error("writeFile-error:{}",e);
+            }
+        }
+
+    }
+}

+ 26 - 0
src/main/java/com/fdkankan/manage_jp/service/impl/SceneEditControlsServiceImpl.java

@@ -0,0 +1,26 @@
+package com.fdkankan.manage_jp.service.impl;
+
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.fdkankan.manage_jp.entity.SceneEditControls;
+import com.fdkankan.manage_jp.mapper.ISceneEditControlsMapper;
+import com.fdkankan.manage_jp.service.ISceneEditControlsService;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import org.springframework.stereotype.Service;
+
+/**
+ * <p>
+ *  服务实现类
+ * </p>
+ *
+ * @author 
+ * @since 2023-04-23
+ */
+@Service
+public class SceneEditControlsServiceImpl extends ServiceImpl<ISceneEditControlsMapper, SceneEditControls> implements ISceneEditControlsService {
+
+    @Override
+    public SceneEditControls getBySceneEditId(Long sceneEditInfoId) {
+        return this.getOne(new LambdaQueryWrapper<SceneEditControls>()
+                .eq(SceneEditControls::getEditInfoId, sceneEditInfoId));
+    }
+}

+ 25 - 0
src/main/java/com/fdkankan/manage_jp/service/impl/SceneEditInfoExtServiceImpl.java

@@ -0,0 +1,25 @@
+package com.fdkankan.manage_jp.service.impl;
+
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.fdkankan.manage_jp.entity.SceneEditInfoExt;
+import com.fdkankan.manage_jp.mapper.ISceneEditInfoExtMapper;
+import com.fdkankan.manage_jp.service.ISceneEditInfoExtService;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import org.springframework.stereotype.Service;
+
+/**
+ * <p>
+ *  服务实现类
+ * </p>
+ *
+ * @author 
+ * @since 2023-04-23
+ */
+@Service
+public class SceneEditInfoExtServiceImpl extends ServiceImpl<ISceneEditInfoExtMapper, SceneEditInfoExt> implements ISceneEditInfoExtService {
+
+    @Override
+    public SceneEditInfoExt getByEditInfoId(Long sceneEditInfoId) {
+        return this.getOne(new LambdaQueryWrapper<SceneEditInfoExt>().eq(SceneEditInfoExt::getEditInfoId, sceneEditInfoId));
+    }
+}

+ 142 - 2
src/main/java/com/fdkankan/manage_jp/service/impl/ScenePlusServiceImpl.java

@@ -1,13 +1,27 @@
 package com.fdkankan.manage_jp.service.impl;
 
+import cn.hutool.core.io.FileUtil;
+import cn.hutool.core.util.StrUtil;
 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
-import com.fdkankan.manage_jp.entity.ScenePlus;
+import com.fdkankan.common.constant.SceneSource;
+import com.fdkankan.common.util.FileUtils;
+import com.fdkankan.fyun.face.FYunFileServiceInterface;
+import com.fdkankan.manage_jp.common.ResultCode;
+import com.fdkankan.manage_jp.entity.*;
+import com.fdkankan.manage_jp.exception.BusinessException;
 import com.fdkankan.manage_jp.mapper.IScenePlusMapper;
-import com.fdkankan.manage_jp.service.IScenePlusService;
+import com.fdkankan.manage_jp.service.*;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.fdkankan.manage_jp.util.SceneResourcePath;
+import com.fdkankan.manage_jp.util.SnowflakeIdGenerator;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 
+import java.io.File;
+import java.util.Date;
 import java.util.List;
 
 /**
@@ -19,8 +33,24 @@ import java.util.List;
  * @since 2022-12-30
  */
 @Service
+@Slf4j
 public class ScenePlusServiceImpl extends ServiceImpl<IScenePlusMapper, ScenePlus> implements IScenePlusService {
 
+    @Autowired
+    IScene3dNumService scene3dNumService;
+    @Autowired
+    IScenePlusExtService scenePlusExtService;
+    @Autowired
+    ISceneEditInfoService sceneEditInfoService;
+    @Autowired
+    ISceneEditInfoExtService sceneEditInfoExtService;
+    @Autowired
+    ISceneEditControlsService sceneEditControlsService;
+    @Autowired
+    FYunFileServiceInterface fYunFileServiceInterface;
+    @Autowired
+    SceneCommonService sceneCommonService;
+
     @Override
     public ScenePlus getByNum(String sceneNum) {
         LambdaQueryWrapper<ScenePlus> wrapper = new LambdaQueryWrapper<>();
@@ -39,4 +69,114 @@ public class ScenePlusServiceImpl extends ServiceImpl<IScenePlusMapper, ScenePlu
         wrapper.set(ScenePlus::getUserId,null);
         this.update(wrapper);
     }
+
+    @Override
+    public void copyScene(ScenePlus scenePlus) {
+        if(scenePlus.getSceneStatus() !=-2){
+            throw new BusinessException(ResultCode.SCENE_ERROR);
+        }
+        String oldNum = scenePlus.getNum();
+        Long plusId = scenePlus.getId();
+        String newNum = scene3dNumService.generateNum();
+        String oldSceneName = scenePlus.getTitle();
+
+        ScenePlusExt plusExt = scenePlusExtService.getByPlusId(plusId);
+        if(plusExt == null){
+            throw new BusinessException(ResultCode.NOT_RECORD);
+        }
+        String oldDataSource = plusExt.getDataSource();
+
+        String newDataSource = sceneCommonService.getNewDataSource(oldDataSource);
+
+        log.info("sceneCopy-V4-oldNum:{},oldDataSource:{},newNum:{},newDataSource:{}",
+                oldNum,oldDataSource,newNum,newDataSource);
+
+        scenePlus.setNum(newNum);
+        scenePlus.setTitle(scenePlus.getTitle() +"(copy)");
+        scenePlus.setId(null);
+        this.save(scenePlus);
+
+        String newVideos = plusExt.getVideos();
+        if(StrUtil.isNotEmpty(newVideos)){
+            newVideos = plusExt.getVideos().replaceAll("/data/data" + oldNum, "/scene_view_data/" + newNum + "/data").replaceAll(oldNum, newNum);
+        }
+        plusExt.setId(null);
+        plusExt.setPlusId(scenePlus.getId());
+        plusExt.setDataSource(newDataSource);
+        plusExt.setWebSite(plusExt.getWebSite().replace(oldNum, newNum));
+        plusExt.setThumb(plusExt.getThumb().replace(oldNum, newNum));
+        plusExt.setVideos(newVideos);
+        plusExt.setViewCount(0);
+        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);
+
+        SceneEditControls sceneEditControls = sceneEditControlsService.getBySceneEditId(sceneEditInfoId);
+        sceneEditControls.setId(null);
+        sceneEditControls.setEditInfoId(sceneEditInfo.getId());
+        sceneEditControlsService.save(sceneEditControls);
+
+
+        try {
+            //重新生成编辑页基础设置二维码
+            sceneCommonService.createNewQrCode(newNum,plusExt.getWebSite());
+            //copyDataSource
+            cn.hutool.core.io.FileUtil.copyContent(new File(oldDataSource),new File(newDataSource),true);
+
+            this.copyOssAndNas(oldNum,newNum);
+
+            //修改 oss status.json ,nas scene.json
+            String targetData = String.format(SceneResourcePath.DATA_VIEW_PATH,newNum);
+            sceneCommonService.updateOssJson(targetData,oldNum,newNum,"v4");
+
+            sceneCommonService.updateNasSceneJson(targetData,oldNum,newNum,oldSceneName,scenePlus.getTitle(),"v4");
+
+        }catch (Exception e){
+            log.error("复制场景失败-V4-sceneNum:{},error:{}",oldNum,e);
+            scenePlus.setSceneStatus(-1);
+            this.updateById(scenePlus);
+            throw new BusinessException(-1,"复制失败");
+        }
+
+    }
+
+    private  void copyOssAndNas(String oldNum,String newNum){
+        // 拷贝场景编辑资源
+        String oldEditPath = String.format(SceneResourcePath.EDIT_PATH_v4, oldNum);
+        String newEditPath = String.format(SceneResourcePath.EDIT_PATH_v4, newNum);
+        fYunFileServiceInterface.copyFileInBucket(oldEditPath, newEditPath);
+
+        // 拷贝场景展示资源
+        String oldViewPath = String.format(SceneResourcePath.VIEW_PATH_v4, oldNum);
+        String newViewPath = String.format(SceneResourcePath.VIEW_PATH_v4, newNum);
+        fYunFileServiceInterface.copyFileInBucket(oldViewPath, newViewPath);
+
+        // 拷贝本地资源
+        String oldPath = SceneResourcePath.nasBasePath + oldNum;
+        String newPath = SceneResourcePath.nasBasePath + newNum;
+        if(new File(oldPath).exists()){
+            FileUtil.copyContent(new File(oldPath), new File(newPath),true);
+        }
+        String oldPath_v4 = SceneResourcePath.nasBasePath_v4 + oldNum;
+        String newPath_v4 = SceneResourcePath.nasBasePath_v4 + newNum;
+        if(new File(oldPath_v4).exists()){
+            FileUtil.copyContent(new File(oldPath_v4), new File(newPath_v4),true);
+        }
+    }
+
+
 }

+ 108 - 1
src/main/java/com/fdkankan/manage_jp/service/impl/SceneProServiceImpl.java

@@ -7,10 +7,12 @@ import com.alibaba.nacos.shaded.org.checkerframework.checker.units.qual.A;
 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.fdkankan.common.constant.ErrorCode;
 import com.fdkankan.common.util.FileUtils;
 import com.fdkankan.fyun.face.FYunFileServiceInterface;
 import com.fdkankan.manage_jp.common.OssPath;
 import com.fdkankan.manage_jp.common.PageInfo;
+import com.fdkankan.manage_jp.common.RedisKeyUtil;
 import com.fdkankan.manage_jp.common.ResultCode;
 import com.fdkankan.manage_jp.entity.Company;
 import com.fdkankan.manage_jp.entity.ScenePlus;
@@ -21,14 +23,22 @@ import com.fdkankan.manage_jp.httpClient.service.LaserService;
 import com.fdkankan.manage_jp.mapper.ISceneProMapper;
 import com.fdkankan.manage_jp.service.*;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.fdkankan.manage_jp.util.GenerateNumUtil;
+import com.fdkankan.manage_jp.util.SceneResourcePath;
+import com.fdkankan.manage_jp.util.SnowflakeIdGenerator;
 import com.fdkankan.manage_jp.vo.request.SceneParam;
 import com.fdkankan.manage_jp.vo.response.SceneVo;
+import com.fdkankan.redis.util.RedisUtil;
 import lombok.extern.slf4j.Slf4j;
 import org.apache.commons.lang3.StringUtils;
 import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
 import org.springframework.stereotype.Service;
 
+import java.io.File;
+import java.util.Date;
 import java.util.HashMap;
+import java.util.HashSet;
 import java.util.List;
 import java.util.stream.Collectors;
 
@@ -56,7 +66,10 @@ public class SceneProServiceImpl extends ServiceImpl<ISceneProMapper, ScenePro>
     IScenePlusExtService scenePlusExtService;
     @Autowired
     FYunFileServiceInterface fYunFileServiceInterface;
-
+    @Autowired
+    IScene3dNumService scene3dNumService;
+    @Autowired
+    SceneCommonService sceneCommonService;
 
     @Override
     public Long getCountByUserIds(List<Long> userIds) {
@@ -182,4 +195,98 @@ public class SceneProServiceImpl extends ServiceImpl<ISceneProMapper, ScenePro>
         wrapper.set(ScenePro::getUserId,null);
         this.update(wrapper);
     }
+
+    @Override
+    public void copyScene(ScenePro scenePro) {
+        if(scenePro.getStatus() !=-2){
+            throw new BusinessException(ResultCode.SCENE_ERROR);
+        }
+        String newNum = scene3dNumService.generateNum();
+        String oldNum = scenePro.getNum();
+
+        String oldDataSource = scenePro.getDataSource();
+        String newDataSource = sceneCommonService.getNewDataSource(oldDataSource);
+
+        log.info("sceneCopy--oldNum:{},oldDataSource:{},newNum:{},newDataSource:{}",
+                oldNum,oldDataSource,newNum,newDataSource);
+
+
+        Long sceneProId = scenePro.getId();
+        String oldSceneName = scenePro.getSceneName();
+        scenePro.setId(null);
+        scenePro.setNum(newNum);
+        scenePro.setSceneName(scenePro.getSceneName() +"(copy)");
+        scenePro.setViewCount(0);
+        scenePro.setWebSite(scenePro.getWebSite().replaceAll(scenePro.getNum(),scenePro.getNum()));
+        scenePro.setThumb(scenePro.getWebSite().replaceAll(scenePro.getNum(),scenePro.getNum()));
+        scenePro.setDataSource(newDataSource);
+        this.save(scenePro);
+
+        SceneProEdit oldEditScene = sceneProEditService.getByProId(sceneProId);
+        oldEditScene.setId(null);
+        oldEditScene.setProId(scenePro.getId());
+        oldEditScene.setScreencapVoiceSrc(oldEditScene.getScreencapVoiceSrc() == null ? null : oldEditScene.getScreencapVoiceSrc().replace(oldNum, scenePro.getNum()));
+        oldEditScene.setScreencapVoiceSound(oldEditScene.getScreencapVoiceSound() == null ? null : oldEditScene.getScreencapVoiceSound().replace(oldNum, scenePro.getNum()));
+        oldEditScene.setScreencapVoiceSoundsync(oldEditScene.getScreencapVoiceSoundsync() == null ? null : oldEditScene.getScreencapVoiceSoundsync().replace(oldNum, scenePro.getNum()));
+        oldEditScene.setPlayData(oldEditScene.getPlayData() == null ? null : oldEditScene.getPlayData().replace(oldNum, scenePro.getNum()));
+        oldEditScene.setScreencapThumb(oldEditScene.getScreencapThumb() == null ? null : oldEditScene.getScreencapThumb().replace(oldNum, scenePro.getNum()));
+        oldEditScene.setFloorPlanPng(oldEditScene.getFloorPlanPng() == null ? null : oldEditScene.getFloorPlanPng().replace(oldNum, scenePro.getNum()));
+        sceneProEditService.save(oldEditScene);
+
+        /*
+         *cp oss nas
+         * data/data{SceneNum}
+         * images/images{SceneNum}
+         * video/video{SceneNum}
+         * voice/voice{SceneNum}
+         */
+        try {
+            //重新生成编辑页基础设置二维码
+            sceneCommonService.createNewQrCode( newNum,scenePro.getWebSite());
+            //copyDataSource
+            cn.hutool.core.io.FileUtil.copyContent(new File(oldDataSource),new File(newDataSource),true);
+
+            String sourceData = String.format(SceneResourcePath.dataPath, oldNum);
+
+            String targetData = String.format(SceneResourcePath.dataPath, scenePro.getNum());
+            this.copyOssAndNas(oldNum,scenePro.getNum(),sourceData,targetData);
+            //修改 oss status.json ,nas scene.json
+            sceneCommonService.updateOssJson(targetData,oldNum,newNum,"v3");
+            sceneCommonService.updateNasSceneJson(targetData,oldNum,newNum,oldSceneName,scenePro.getSceneName(),"v3");
+
+            String sourceImages = String.format(SceneResourcePath.imagesPath, oldNum);
+            String targetImages = String.format(SceneResourcePath.imagesPath, scenePro.getNum());
+            this.copyOssAndNas(oldNum,scenePro.getNum(),sourceImages,targetImages);
+
+            String sourceVideo = String.format(SceneResourcePath.videoPath, oldNum);
+            String targetVideo = String.format(SceneResourcePath.videoPath, scenePro.getNum());
+            this.copyOssAndNas(oldNum,scenePro.getNum(),sourceVideo,targetVideo);
+
+            String sourceVoice = String.format(SceneResourcePath.voicePath, oldNum);
+            String targetVoice = String.format(SceneResourcePath.voicePath, scenePro.getNum());
+            this.copyOssAndNas(oldNum,scenePro.getNum(),sourceVoice,targetVoice);
+
+        }catch ( Exception e){
+            log.error("复制场景失败-sceneNum:{},error:{}",oldNum,e);
+            scenePro.setStatus(-1);
+            this.updateById(scenePro);
+            throw new BusinessException(-1,"复制失败");
+        }
+
+
+    }
+
+    private void copyOssAndNas(String oldNum ,String newNum ,String sourcePath,String targetPath){
+        log.info("sceneCopy-ossSource-oldNum:{},newNum:{},sourcePath:{},targetPath:{}",oldNum,newNum,sourcePath,targetPath);
+        fYunFileServiceInterface.copyFileInBucket(sourcePath,targetPath);
+        File fileData = new File(SceneResourcePath.nasBasePath + sourcePath);
+        if(fileData.exists()){
+            cn.hutool.core.io.FileUtil.copyContent(fileData,new File(SceneResourcePath.nasBasePath + targetPath),true);
+        }
+    }
+
+
+
+
+
 }

+ 21 - 0
src/main/java/com/fdkankan/manage_jp/util/FileUtil.java

@@ -0,0 +1,21 @@
+package com.fdkankan.manage_jp.util;
+
+import java.io.*;
+
+public class FileUtil {
+
+    public static void writeFile(String filePath,String str) throws IOException {
+
+        File fout = new File(filePath);
+        if(!fout.getParentFile().exists()){
+            fout.getParentFile().mkdirs();
+        }
+        if(!fout.exists()){
+            fout.createNewFile();
+        }
+        FileOutputStream fos = new FileOutputStream(fout);
+        BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(fos));
+        bw.write(str);
+        bw.close();
+    }
+}

+ 20 - 0
src/main/java/com/fdkankan/manage_jp/util/GenerateNumUtil.java

@@ -0,0 +1,20 @@
+package com.fdkankan.manage_jp.util;
+
+import org.apache.commons.lang3.RandomStringUtils;
+
+import java.util.HashSet;
+
+public class GenerateNumUtil {
+
+    public static HashSet<String> generateNum(Integer count ) {
+        HashSet<String> codes = new HashSet<>();
+        for (int i =0 ;i <=count ;i++){
+            codes.add( RandomStringUtils.random(9,true,true));
+        }
+       return codes;
+    }
+    public static String generateNum() {
+        return RandomStringUtils.random(9,true,true);
+    }
+
+}

+ 28 - 0
src/main/java/com/fdkankan/manage_jp/util/SceneResourcePath.java

@@ -0,0 +1,28 @@
+package com.fdkankan.manage_jp.util;
+
+public class SceneResourcePath {
+    /*
+     * data/data{SceneNum}
+     * images/images{SceneNum}
+     * video/video{SceneNum}
+     * voice/voice{SceneNum}
+     */
+    public static String nasBasePath = "/mnt/4Dkankan/scene/";
+    public static String nasBasePath_v4 = "/mnt/4Dkankan/scene_v4/";
+    public static String qrCodeBasePath = "/mnt/4Dkankan/sceneQRcode/";
+
+    public static String dataPath = "data/data%s";
+    public static String imagesPath = "images/images%s";
+    public static String videoPath = "video/video%s";
+    public static String voicePath = "voice/voice%s";
+
+
+    public static final String EDIT_PATH_v4 =  "scene_edit_data/%s/";
+    public static final String VIEW_PATH_v4 =  "scene_view_data/%s/";
+
+    public static final String DATA_EDIT_PATH =  "scene_edit_data/%s/data/";
+    public static final String DATA_VIEW_PATH =  "scene_view_data/%s/data/";
+
+    public static final String DOWNLOADS_QRCODE = "downloads/scene/%s/QRcode/";
+
+}

+ 137 - 0
src/main/java/com/fdkankan/manage_jp/util/SnowflakeIdGenerator.java

@@ -0,0 +1,137 @@
+package com.fdkankan.manage_jp.util;
+
+/**
+ * Twitter_Snowflake<br>
+ * SnowFlake的结构如下(每部分用-分开):<br>
+ * 0 - 0000000000 0000000000 0000000000 0000000000 0 - 00000 - 00000 - 000000000000 <br>
+ * 1位标识,由于long基本类型在Java中是带符号的,最高位是符号位,正数是0,负数是1,所以id一般是正数,最高位是0<br>
+ * 41位时间截(毫秒级),注意,41位时间截不是存储当前时间的时间截,而是存储时间截的差值(当前时间截 - 开始时间截)
+ * 得到的值),这里的的开始时间截,一般是我们的id生成器开始使用的时间,由我们程序来指定的(如下下面程序IdWorker类的startTime属性)。41位的时间截,可以使用69年,年T = (1L << 41) / (1000L * 60 * 60 * 24 * 365) = 69<br>
+ * 10位的数据机器位,可以部署在1024个节点,包括5位datacenterId和5位workerId<br>
+ * 12位序列,毫秒内的计数,12位的计数顺序号支持每个节点每毫秒(同一机器,同一时间截)产生4096个ID序号<br>
+ * 加起来刚好64位,为一个Long型。<br>
+ * SnowFlake的优点是,整体上按照时间自增排序,并且整个分布式系统内不会产生ID碰撞(由数据中心ID和机器ID作区分),并且效率较高,经测试,SnowFlake每秒能够产生26万ID左右。
+ */
+public class SnowflakeIdGenerator {
+
+    // ==============================Fields===========================================
+    /** 开始时间截 (2015-01-01) */
+    private final long twepoch = 1420041600000L;
+
+    /** 机器id所占的位数 */
+    private final long workerIdBits = 5L;
+
+    /** 数据标识id所占的位数 */
+    private final long datacenterIdBits = 5L;
+
+    /** 支持的最大机器id,结果是31 (这个移位算法可以很快的计算出几位二进制数所能表示的最大十进制数) */
+    private final long maxWorkerId = -1L ^ (-1L << workerIdBits);
+
+    /** 支持的最大数据标识id,结果是31 */
+    private final long maxDatacenterId = -1L ^ (-1L << datacenterIdBits);
+
+    /** 序列在id中占的位数 */
+    private final long sequenceBits = 12L;
+
+    /** 机器ID向左移12位 */
+    private final long workerIdShift = sequenceBits;
+
+    /** 数据标识id向左移17位(12+5) */
+    private final long datacenterIdShift = sequenceBits + workerIdBits;
+
+    /** 时间截向左移22位(5+5+12) */
+    private final long timestampLeftShift = sequenceBits + workerIdBits + datacenterIdBits;
+
+    /** 生成序列的掩码,这里为4095 (0b111111111111=0xfff=4095) */
+    private final long sequenceMask = -1L ^ (-1L << sequenceBits);
+
+    /** 工作机器ID(0~31) */
+    private long workerId;
+
+    /** 数据中心ID(0~31) */
+    private long datacenterId;
+
+    /** 毫秒内序列(0~4095) */
+    private long sequence = 0L;
+
+    /** 上次生成ID的时间截 */
+    private long lastTimestamp = -1L;
+
+    public static  SnowflakeIdGenerator snowflakeIdGenerator = new SnowflakeIdGenerator(1,1);
+
+    //==============================Constructors=====================================
+    /**
+     * 构造函数
+     * @param workerId 工作ID (0~31)
+     * @param datacenterId 数据中心ID (0~31)
+     */
+    private SnowflakeIdGenerator(long workerId, long datacenterId) {
+        if (workerId > maxWorkerId || workerId < 0) {
+            throw new IllegalArgumentException(String.format("worker Id can't be greater than %d or less than 0", maxWorkerId));
+        }
+        if (datacenterId > maxDatacenterId || datacenterId < 0) {
+            throw new IllegalArgumentException(String.format("datacenter Id can't be greater than %d or less than 0", maxDatacenterId));
+        }
+        this.workerId = workerId;
+        this.datacenterId = datacenterId;
+    }
+
+    // ==============================Methods==========================================
+    /**
+     * 获得下一个ID (该方法是线程安全的)
+     * @return SnowflakeId
+     */
+    public synchronized long nextId() {
+        long timestamp = timeGen();
+
+        //如果当前时间小于上一次ID生成的时间戳,说明系统时钟回退过这个时候应当抛出异常
+        if (timestamp < lastTimestamp) {
+            throw new RuntimeException(
+                    String.format("Clock moved backwards.  Refusing to generate id for %d milliseconds", lastTimestamp - timestamp));
+        }
+
+        //如果是同一时间生成的,则进行毫秒内序列
+        if (lastTimestamp == timestamp) {
+            sequence = (sequence + 1) & sequenceMask;
+            //毫秒内序列溢出
+            if (sequence == 0) {
+                //阻塞到下一个毫秒,获得新的时间戳
+                timestamp = tilNextMillis(lastTimestamp);
+            }
+        }
+        //时间戳改变,毫秒内序列重置
+        else {
+            sequence = 0L;
+        }
+
+        //上次生成ID的时间截
+        lastTimestamp = timestamp;
+
+        //移位并通过或运算拼到一起组成64位的ID
+        return ((timestamp - twepoch) << timestampLeftShift) //
+                | (datacenterId << datacenterIdShift) //
+                | (workerId << workerIdShift) //
+                | sequence;
+    }
+
+    /**
+     * 阻塞到下一个毫秒,直到获得新的时间戳
+     * @param lastTimestamp 上次生成ID的时间截
+     * @return 当前时间戳
+     */
+    protected long tilNextMillis(long lastTimestamp) {
+        long timestamp = timeGen();
+        while (timestamp <= lastTimestamp) {
+            timestamp = timeGen();
+        }
+        return timestamp;
+    }
+
+    /**
+     * 返回以毫秒为单位的当前时间
+     * @return 当前时间(毫秒)
+     */
+    protected long timeGen() {
+        return System.currentTimeMillis();
+    }
+}

+ 5 - 0
src/main/resources/mapper/manage_jp/Scene3dNumMapper.xml

@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="com.fdkankan.manage_jp.mapper.IScene3dNumMapper">
+
+</mapper>

+ 5 - 0
src/main/resources/mapper/manage_jp/SceneEditControlsMapper.xml

@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="com.fdkankan.manage_jp.mapper.ISceneEditControlsMapper">
+
+</mapper>

+ 5 - 0
src/main/resources/mapper/manage_jp/SceneEditInfoExtMapper.xml

@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="com.fdkankan.manage_jp.mapper.ISceneEditInfoExtMapper">
+
+</mapper>