瀏覽代碼

新增
四维看看转大场景接口
树列表分页功能

wuweihao 4 年之前
父節點
當前提交
1443ce8c0a

+ 7 - 0
README.md

@@ -8,6 +8,13 @@
 service:8.135.106.227 项目测试服务器 
 doc: http://8.135.106.227:8004/doc.html
 
+更新
+    2021-06-22 
+        1.四维看看转大场景功能
+        2.数据库tb_scene 增加字段parent_id , version     
+       ALTER TABLE tb_scene ADD parent_id bigint(10) NULL DEFAULT NULL COMMENT '父id';
+       ALTER TABLE tb_scene ADD version int(8) NULL DEFAULT NULL COMMENT '版本,只有父有';
+
 
 
 # pro

+ 1 - 0
gis_application/src/main/resources/application.properties

@@ -36,3 +36,4 @@ pagehelper.support-methods-arguments=true
 
 
 
+

+ 89 - 0
gis_application/src/main/resources/data/someData.json

@@ -0,0 +1,89 @@
+{
+  "model": {
+    "sid": "zhengzhou",
+    "name": "526190409SZGX",
+    "status": "viewable",
+    "floors": "",
+    "metainfo": { "allowed_methods": ["GET", "OPTIONS", "HEAD"] },
+    "images": [
+      {
+        "metadata": "{\"camera_mode\":0,\"camera_position\":{\"x\":17.319578170776367,\"y\":0.5689632296562195,\"z\":30.42438507080078},\"camera_quaternion\":{\"x\":-0.0000020361233819675194,\"y\":0.9999978870169733,\"z\":-0.0012442941874225735,\"w\":-0.0016363646960161576},\"ortho_zoom\":-1,\"ss_zoom\":1,\"scan_id\":\"b1498df53a554a0bafec6646639964e6\",\"is_ortho\":false,\"floorVisibility\":[1]}",
+        "created": "2019-04-12T01:15:48.811428Z",
+        "modified": "2019-04-12T01:15:48.811961Z",
+        "sid": "3itPh3K83Bq",
+        "name": "04.12.2019_09.15.38",
+        "height": 1707,
+        "width": 3034,
+        "is_hero": true,
+        "category": "user",
+        "vision_generated_label": "",
+        "vision_generated_name": "",
+        "vision_image_index": -1,
+        "created_by": 4084,
+        "rating": null
+      }
+    ],
+    "job": { "uuid": "dacf7dfa24ae47fab8fcebfe4dc41ab9" },
+    "player_options": {
+      "presented_by": true,
+      "highlight_reel": true,
+      "floor_plan": true,
+      "tour_buttons": true,
+      "dollhouse": true,
+      "fast_transitions": false,
+      "autoplay": false,
+      "contact_email": true,
+      "address": true,
+      "contact_name": true,
+      "model_summary": true,
+      "contact_phone": true,
+      "model_name": true,
+      "external_url": true
+    },
+    "modified": "2019-04-12T06:39:16.940410Z",
+    "is_public": true,
+    "summary": "",
+    "presented_by": "",
+    "contact_name": "",
+    "contact_phone": "",
+    "formatted_contact_phone": "",
+    "contact_email": "",
+    "external_url": "",
+    "camera_start": {
+      "camera": {
+        "zoom": "-1",
+        "quaternion": ["0.7013", "-0.7026", "0.0907", "-0.08"]
+      },
+      "pano": { "uuid": "2" },
+      "mode": "0"
+    }
+  },
+  "files": { "templates": ["data/{{number}}/{{filename}}"] },
+  "name": "526190409SZGX",
+  "summary": "",
+  "hoticon": {
+    "default": "images/4dagePoint2.png",
+    "higt": "images/4dagePoint.png"
+  },
+  "camera_start": {
+    "camera": {
+      "zoom": "-1",
+      "quaternion": ["0.7013", "-0.7026", "0.0907", "-0.08"]
+    },
+    "pano": { "uuid": "2" },
+    "mode": "0"
+  },
+  "loadlogo": false,
+  "special": false,
+  "vision_version": "1.1.562.17209",
+  "hotImageScale": false,
+  "hideFloorMarker": false,
+  "hideMouseMarker": false,
+  "floorMarkerColor": "#4bcdfc",
+  "mouseMarkerColor": "#4bcdfc",
+  "momentTour": "walk",
+  "showHotListSta": false,
+  "hotIconScale": "1",
+  "supportsVR": false,
+  "weixinDesc": ""
+}

+ 0 - 4
gis_common/src/main/java/com/gis/common/constant/ConfigConstant.java

@@ -72,8 +72,4 @@ public class ConfigConstant {
     public  String iotSign;
 
 
-
-
-
-
 }

+ 6 - 0
gis_common/src/main/java/com/gis/common/constant/MsgCode.java

@@ -22,6 +22,12 @@ public class MsgCode {
     /** 作品已被删除,无法编辑 */
     public final static Integer e3006 = 3006;
 
+    /** 302x 文件类型校验 , 文件不存在 */
+    public final static Integer e3020 = 3020;
+
+    /** 302x 文件类型校验 , 非法文件 */
+    public final static Integer e3021 = 3021;
+
     public final static Integer e5003 = 5003;
     public final static String m5003 = "不支持此图片";
 

+ 36 - 3
gis_common/src/main/java/com/gis/common/util/FileUtils.java

@@ -9,12 +9,11 @@ import com.gis.common.exception.BaseRuntimeException;
 import lombok.extern.slf4j.Slf4j;
 import org.apache.commons.lang3.StringUtils;
 import org.junit.Test;
+import org.springframework.core.io.ClassPathResource;
 import org.springframework.util.ResourceUtils;
 import org.springframework.web.multipart.MultipartFile;
 
-import java.io.File;
-import java.io.IOException;
-import java.io.InputStream;
+import java.io.*;
 import java.net.URL;
 import java.util.*;
 
@@ -226,4 +225,38 @@ public class FileUtils {
         log.info("存在非法参数不能放行!请核对上传文件格式,重新刷新页面再次上传!");
         return false;
     }
+
+
+    /**
+     * 读取资源文内容
+     * jar包运行,只能用文件流的形式获取文件
+     *
+     * @param resourcePath : data/someData.json 填写相对路径
+     * @return
+     */
+    public static String getResourceContent(String resourcePath){
+        ClassPathResource classPathResource = new ClassPathResource(resourcePath);
+        InputStream resource = null;
+        try {
+            resource = classPathResource.getInputStream();
+        } catch (IOException e) {
+            e.printStackTrace();
+        }
+        StringBuilder sb = new StringBuilder();
+        String line;
+        String str = null ;
+        BufferedReader br = new BufferedReader(new InputStreamReader(resource));
+        while (true) {
+            try {
+                if ((line = br.readLine()) == null) break;
+                sb.append(line);
+                str = sb.toString();
+            } catch (IOException e) {
+                e.printStackTrace();
+            }
+        }
+        return str;
+    }
+
+
 }

+ 4 - 6
gis_domain/src/main/java/com/gis/domain/po/SceneEntity.java

@@ -26,16 +26,14 @@ public class SceneEntity extends BaseEntity implements Serializable {
 //    @ApiModelProperty(value = "场景url")
 //    private String webSite;
 
-//    @ApiModelProperty(value = "简介")
-//    private String description;
+    @ApiModelProperty(value = "父级id")
+    private Long parentId;
 
 
     @ApiModelProperty(value = "是否显示,1:是, 0:否")
     private Integer display;
 
-
-
-//    @ApiModelProperty(value = "排序")
-//    private Integer sort;
+    @ApiModelProperty(value = "版本")
+    private Integer version;
 
 }

+ 6 - 0
gis_mapper/src/main/java/com/gis/mapper/SceneMapper.java

@@ -35,4 +35,10 @@ public interface SceneMapper extends IBaseMapper<SceneEntity, Long> {
 
     @Update("update tb_scene set display = 0 where is_delete = '0' and display = 1 and type = #{type}")
     void setDisableByType(String type);
+
+    @Select("select * from tb_scene where is_delete=0 and scene_code like #{sceneCode} order by create_time desc limit 1")
+    SceneEntity findBySceneCodeLike(String sceneCode);
+
+    @Update("update tb_scene set version = version + 1 , update_time = NOW() where is_delete=0 and id=#{id} ")
+    void addVersion(Long id);
 }

+ 14 - 0
gis_service/src/main/java/com/gis/service/AgeService.java

@@ -0,0 +1,14 @@
+package com.gis.service;
+
+
+import com.gis.common.util.Result;
+import org.springframework.web.multipart.MultipartFile;
+
+/**
+ * Created by owen on 2020/3/11 0011 16:14
+ */
+public interface AgeService  {
+
+
+    Result uploadAge(MultipartFile file);
+}

+ 10 - 2
gis_service/src/main/java/com/gis/service/SceneService.java

@@ -7,8 +7,6 @@ import com.gis.domain.dto.RoamViableDto;
 import com.gis.domain.dto.SceneDataDto;
 import com.gis.domain.po.SceneEntity;
 
-import java.util.List;
-
 
 /**
  * Created by owen on 2020/3/11 0011 16:14
@@ -27,4 +25,14 @@ public interface SceneService extends IBaseService<SceneEntity, Long> {
     Result edit(SceneDataDto param);
 
     Result display(Long id);
+
+    /**
+     * 根据场景码模块搜索, 只要最新的一条记录
+     * @param sceneCode
+     * @return
+     */
+    SceneEntity findBySceneCodeLike(String sceneCode);
+
+    void addVersion(Long id);
+    Result listTree(PageDto param);
 }

+ 6 - 7
gis_service/src/main/java/com/gis/service/aop/WebLogAspect.java

@@ -29,19 +29,17 @@ public class WebLogAspect {
     @Autowired
     private HttpServletRequest request;
 
-
+    private long startTime ;
 
     @Pointcut("execution(* com.gis.web.controller.*.*(..))")//切入点描述 这个是controller包的切入点
     public void controllerLog(){}//签名,可以理解成这个切入点的一个名称
 
     @Before("controllerLog()") //在切入点的方法run之前要干的
     public void logBeforeController(JoinPoint joinPoint) throws Exception {
-
+        startTime = System.currentTimeMillis();
         // 记录下请求内容
-        log.warn("start : {}" , request.getRequestURI());
-        log.info("request Method : {}" , request.getMethod());
-        log.info("request IP : {}" , request.getRemoteAddr());
-        log.info("request Args : {}" , Arrays.toString(joinPoint.getArgs()));
+        log.warn("start:{}, uuid:{}" , request.getRequestURI(), startTime);
+        log.info("request Method : {}, IP : {}" , request.getMethod() , request.getRemoteAddr());
 
         // 获取token
         String token = request.getHeader("token");
@@ -84,7 +82,8 @@ public class WebLogAspect {
     public void doAfterReturning(Object ret) throws Throwable {
         // 处理完请求,返回内容
 //        log.info("响应RESPONSE : " + ret.toString());
-        log.warn("end : {}", request.getRequestURI());
+//        log.warn("end : {}", request.getRequestURI());
+        log.warn("end:{}, uuid:{}, 响应耗时:{} ms" , request.getRequestURI(), startTime, (System.currentTimeMillis() - startTime));
     }
 
     /**

+ 296 - 0
gis_service/src/main/java/com/gis/service/impl/AgeServiceImpl.java

@@ -0,0 +1,296 @@
+package com.gis.service.impl;
+
+import cn.hutool.core.io.FileUtil;
+import cn.hutool.core.util.ZipUtil;
+import com.alibaba.fastjson.JSONArray;
+import com.alibaba.fastjson.JSONObject;
+import com.gis.common.constant.ConfigConstant;
+import com.gis.common.constant.MsgCode;
+import com.gis.common.exception.BaseRuntimeException;
+import com.gis.common.proto.util.ConvertUtils;
+import com.gis.common.util.FileUtils;
+import com.gis.common.util.Result;
+import com.gis.domain.po.SceneEntity;
+import com.gis.service.AgeService;
+import com.gis.service.SceneService;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.lang3.StringUtils;
+import org.junit.Test;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import org.springframework.web.multipart.MultipartFile;
+
+import java.io.File;
+import java.io.IOException;
+
+
+/**
+ * Created by owen on 2021/6/22 0011 16:16
+ */
+@Slf4j
+@Service
+public class AgeServiceImpl implements AgeService {
+
+    @Autowired
+    SceneService sceneService;
+
+    @Autowired
+    ConfigConstant configConstant;
+
+    @Override
+    public Result uploadAge(MultipartFile file) {
+
+
+        String sceneCode = getSceneCode(file);
+
+        SceneEntity dbEntity = sceneService.findBySceneCode(sceneCode);
+        String newSceneCode;
+        if (dbEntity == null) {
+            //创建父级
+            dbEntity = new SceneEntity();
+            dbEntity.setSceneCode(sceneCode);
+            dbEntity.setVersion(1);
+            sceneService.save(dbEntity);
+            newSceneCode = sceneCode + "_" + dbEntity.getVersion();
+        } else {
+            int version = dbEntity.getVersion() + 1;
+            newSceneCode = sceneCode + "_" + version;
+        }
+
+        String basePath = configConstant.serverBasePath + "/age/" + newSceneCode;
+        // 把zip写入服务器,并用新的版本场景码命名
+        unZip(basePath, file);
+
+        // 检查 images+场景码目录是否存在
+        String ageBaseSceneCodePath = basePath + "/v3local/images/images" + sceneCode;
+
+        // vision.modeldata -> vision.json: visibles2、visibles3 删除 -> vision.modeldata
+        visionModelDataToVision(ageBaseSceneCodePath);
+        editVision(ageBaseSceneCodePath);
+        VisionToVisionModelData(ageBaseSceneCodePath);
+        createSomeDataJaon(ageBaseSceneCodePath, newSceneCode);
+        createData2Js(ageBaseSceneCodePath);
+        String scenePath = configConstant.serverBasePath + "/" + newSceneCode;
+        moveFile(ageBaseSceneCodePath, scenePath);
+
+        SceneEntity sceneEntity = new SceneEntity();
+        sceneEntity.setSceneCode(newSceneCode);
+        sceneEntity.setPath("/data/" + newSceneCode);
+        Long parentId = dbEntity.getId();
+        sceneEntity.setParentId(parentId);
+        sceneService.save(sceneEntity);
+        // 父级版本号加1
+        sceneService.addVersion(parentId);
+
+        return Result.success();
+
+
+    }
+
+
+    /**
+     * @param filePath 文件全路径
+     */
+    private static void existFile(String filePath) {
+        if (!FileUtil.isFile(filePath)) {
+            throw new BaseRuntimeException(MsgCode.e3021, "文件不存在, path:" + filePath);
+        }
+    }
+
+    private static void existDir(String filePath) {
+        if (!FileUtil.isDirectory(filePath)) {
+            throw new BaseRuntimeException(MsgCode.e3021, "目录不存在, path:" + filePath);
+        }
+    }
+
+    private static void unZip(String basePath, MultipartFile file) {
+        String zipPath = basePath + ".zip";
+        try {
+            FileUtil.writeFromStream(file.getInputStream(), zipPath);
+            log.info("zip写入完成,path: {}", zipPath);
+
+            existFile(zipPath);
+            // 解压文件
+            ZipUtil.unzip(zipPath);
+            log.info("zip解压完成, path: {}", basePath);
+        } catch (IOException e) {
+            e.printStackTrace();
+        }
+
+    }
+
+    /**
+     * 获取场景码
+     *
+     * @param file
+     * @return
+     */
+    private static String getSceneCode(MultipartFile file) {
+        if (!FileUtils.checkFile(file)) {
+            throw new BaseRuntimeException(MsgCode.e3021, "非法文件,只能能上传zip文件");
+        }
+
+        String originalFilename = file.getOriginalFilename();
+        if (!originalFilename.endsWith(".zip")) {
+            throw new BaseRuntimeException(MsgCode.e3021, "非法文件,只能能上传zip文件");
+        }
+
+        String sceneCode = StringUtils.substringBeforeLast(originalFilename, ".");
+        return sceneCode;
+    }
+
+    private static void createData2Js(String basePath) {
+        String data2Path = basePath + "/data2.js";
+        FileUtil.writeUtf8String("{}", data2Path);
+        log.info("新的data2.js写入完成, path:{}", data2Path);
+    }
+
+
+    /***
+     * 处理场景码, 在原来的后缀加1
+     * @param sceneCode
+     * @return
+     */
+    private static String getCode(String sceneCode) {
+        String s = StringUtils.substringAfterLast(sceneCode, "_");
+        sceneCode = StringUtils.substringBeforeLast(sceneCode, "_");
+        int i = Integer.valueOf(s) + 1;
+        return sceneCode + "_" + i;
+    }
+
+
+    /**
+     * @param basePath 父级目录
+     * @throws Exception
+     */
+    private static void visionModelDataToVision(String basePath) {
+        String visionModelDataPath = basePath + "/vision.modeldata";
+        if (!FileUtil.isFile(visionModelDataPath)) {
+            throw new BaseRuntimeException(MsgCode.e3021, "vision.modeldata不存在,path:" + visionModelDataPath);
+        }
+        String visionJsonPath = basePath + "/vision.json";
+        log.info("visionModelDataPath: " + visionModelDataPath);
+        log.info("visionJsonPath: " + visionJsonPath);
+        try {
+            ConvertUtils.convertVisionModelDataToTxt(visionModelDataPath, visionJsonPath);
+            log.info("VisionModelDataToVisionJson转换完成");
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+    }
+
+    /**
+     * @param basePath 父级目录
+     * @return
+     */
+    private static void VisionToVisionModelData(String basePath) {
+
+        String visionJsonPath = basePath + "/vision.json";
+        if (!FileUtil.isFile(visionJsonPath)) {
+            throw new BaseRuntimeException(MsgCode.e3021, "vision.json不存在,path:" + visionJsonPath);
+        }
+        String visionModelDataPath = basePath + "/vision.modeldata";
+        log.info("visionModelDataPath: " + visionModelDataPath);
+        log.info("visionJsonPath: " + visionJsonPath);
+
+        try {
+            ConvertUtils.convertTxtToVisionModelData(visionJsonPath, visionModelDataPath);
+            log.info("visionJsonToVisionModelData转换完成");
+            // 删除vision.json
+//            FileUtil.del(visionJsonPath);
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+
+
+    }
+
+    /**
+     * 编辑vision.json 删除visibles2、visibles3 节点
+     *
+     * @param basePath 父级目录
+     */
+    private static void editVision(String basePath) {
+
+        String visionJsonPath = basePath + "/vision.json";
+        if (!FileUtil.isFile(visionJsonPath)) {
+            throw new BaseRuntimeException(MsgCode.e3021, "vision.json不存在,path:" + visionJsonPath);
+        }
+
+        String in = FileUtil.readUtf8String(visionJsonPath);
+        JSONObject contentJson = JSONObject.parseObject(in);
+        JSONArray sweepLocations = contentJson.getJSONArray("sweepLocations");
+
+        // fori循环才能正确删除节点
+        for (int i = 0; i < sweepLocations.size(); i++) {
+            JSONObject indexJson = sweepLocations.getJSONObject(i);
+            indexJson.remove("visibles2");
+            indexJson.remove("visibles3");
+        }
+
+//        log.info("vision: "+ contentJson.toJSONString());
+        FileUtil.writeUtf8String(contentJson.toJSONString(), visionJsonPath);
+        log.info("新的vision.json写入完成, path:{}", visionJsonPath);
+    }
+
+    /**
+     * 创建someData.json
+     *
+     * @param basePath
+     */
+    private static void createSomeDataJaon(String basePath, String sceneCode) {
+
+        // 获取基础someData.json
+        String content = FileUtils.getResourceContent("data/someData.json");
+        JSONObject contentJson = JSONObject.parseObject(content);
+        JSONObject modelJson = contentJson.getJSONObject("model");
+        // 更新新的场景码
+        modelJson.put("sid", sceneCode);
+        String someDataJsonPath = basePath + "/someData.json";
+
+        FileUtil.writeUtf8String(contentJson.toJSONString(), someDataJsonPath);
+        log.info("someData.json写入完成, path:{}", someDataJsonPath);
+        existFile(someDataJsonPath);
+    }
+
+    /**
+     * 移动文件,并做相应的操作
+     *
+     * @param basePath
+     * @param outPath  移动位置
+     */
+    private static void moveFile(String basePath, String outPath) {
+        File file = new File(basePath);
+        File[] files = file.listFiles();
+        for (File every : files) {
+            String filePath = every.getAbsolutePath();
+            if (filePath.endsWith(".png")) {
+                FileUtil.del(filePath);
+            }
+            // 重命名文件
+            if (filePath.endsWith("_high1")) {
+                String highPath = filePath.substring(0, filePath.length() - 1);
+                if (FileUtil.exist(highPath)) {
+                    FileUtil.del(highPath);
+                }
+                // isRetainExt: 原文件是否保留
+                FileUtil.rename(new File(filePath), highPath, false, true);
+            }
+        }
+        // 删除无用文件 vision2.modeldata
+        FileUtil.del(basePath + "/vision2.modeldata");
+
+        FileUtil.copyContent(file, new File(outPath), true);
+        existDir(outPath);
+        log.info("大场景移动完成, path: {}", outPath);
+    }
+
+
+    @Test
+    public void reName() {
+        String a = "F:\\work\\test\\fcb";
+        String b = "F:\\work\\test\\fcb11";
+//        FileUtil.rename(new File(a), b, false, true);
+        System.out.println(b.substring(0, b.length() - 1));
+    }
+}

+ 28 - 1
gis_service/src/main/java/com/gis/service/impl/SceneServiceImpl.java

@@ -14,13 +14,15 @@ import com.gis.domain.po.SceneEntity;
 import com.gis.mapper.SceneMapper;
 import com.gis.mapper.IBaseMapper;
 import com.gis.service.SceneService;
+import com.gis.service.tree.SceneTreeUtil;
+import com.gis.service.tree.vo.SceneTree;
 import com.github.pagehelper.PageInfo;
-import lombok.extern.log4j.Log4j2;
 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.util.List;
 import java.util.Set;
 
 
@@ -54,6 +56,17 @@ public class SceneServiceImpl extends IBaseServiceImpl<SceneEntity, Long> implem
         return Result.success(page);
     }
 
+    @Override
+    public Result listTree(PageDto param) {
+        startPage(param);
+        List<SceneEntity> search = entityMapper.search(param);
+        SceneTreeUtil tree = new SceneTreeUtil(search);
+        // 按照父亲分页
+        List<SceneTree> sceneTrees = tree.buildTree();
+        PageInfo<SceneTree> page = new PageInfo<>(sceneTrees);
+        return Result.success(page);
+    }
+
     /**
      * 漫游可行
      */
@@ -311,6 +324,20 @@ public class SceneServiceImpl extends IBaseServiceImpl<SceneEntity, Long> implem
         return Result.success();
     }
 
+
+    @Override
+    public SceneEntity findBySceneCodeLike(String sceneCode) {
+        sceneCode = "%" + sceneCode + "%";
+        return entityMapper.findBySceneCodeLike(sceneCode);
+    }
+
+    @Override
+    public void addVersion(Long id) {
+        entityMapper.addVersion(id);
+    }
+
+
+
     /**
      * 2021.04.02 处理infoAttribute的m_title
      * String url  = "https://www.4dmodel.com/SuperTwo/hot_online/index.html?m=" + key;

+ 104 - 0
gis_service/src/main/java/com/gis/service/tree/SceneTreeUtil.java

@@ -0,0 +1,104 @@
+package com.gis.service.tree;
+
+import com.gis.domain.po.SceneEntity;
+import com.gis.service.tree.vo.SceneTree;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class SceneTreeUtil {
+
+    private List<SceneTree> resultNodes = new ArrayList<SceneTree>();//树形结构排序之后list内容
+
+    private List<SceneTree> nodes = new ArrayList<SceneTree>();
+    //传入list参数
+
+    public SceneTreeUtil(List<SceneEntity> nodesList) {//通过构造函数初始化
+        for (SceneEntity n : nodesList) {
+            SceneTree treeGrid = new SceneTree();
+            treeGrid.setId(n.getId());
+            treeGrid.setSceneTitle(n.getSceneTitle());
+            treeGrid.setSceneCode(n.getSceneCode());
+
+//            if (n.getAuthority() != null){
+//                treeGrid.setAuthority(n.getAuthority());
+//            }
+
+            if (n.getParentId() != null) {
+                treeGrid.setParentId(n.getParentId());
+            }
+            nodes.add(treeGrid);
+        }
+    }
+
+    public SceneTreeUtil() {
+    }
+
+    /**
+     * 构建树形结构list
+     *
+     * @return 返回树形结构List列表
+     */
+    public List<SceneTree> buildTree() {
+        for (SceneTree node : nodes) {
+            Long id = node.getParentId();
+            if (id == null) {//通过循环一级节点 就可以通过递归获取二级以下节点
+                resultNodes.add(node);//添加一级节点
+//                node.setLevel(1);
+                build(node, node.getLevel());//递归获取二级、三级、。。。节点
+            }
+        }
+        return resultNodes;
+    }
+
+    /**
+     * 递归循环子节点
+     *
+     * @param node 当前节点
+     */
+    private void build(SceneTree node, int level) {
+        List<SceneTree> children = getChildren(node);
+        if (!children.isEmpty()) {//如果存在子节点
+            node.setChildren(children);
+//        	level++;
+            for (SceneTree child : children) {//将子节点遍历加入返回值中
+//        		child.setLevel(level);
+                build(child, child.getLevel());
+            }
+        }
+    }
+
+    /**
+     * @param node
+     * @return 返回
+     */
+    private List<SceneTree> getChildren(SceneTree node) {
+        List<SceneTree> children = new ArrayList<SceneTree>();
+        Long id = node.getId();
+        for (SceneTree child : nodes) {
+            if (id.equals(child.getParentId())) {//如果id等于父id
+                children.add(child);//将该节点加入循环列表中
+            }
+        }
+        return children;
+    }
+
+//    public List<SceneTree> buildTree(List<SceneEntity> all, List<SceneEntity> in) {
+//        for (SceneEntity n : all) {
+//            SceneTree treeGrid = new SceneTree();
+//            treeGrid.setId(n.getId());
+//            treeGrid.setName(n.getName());
+//            for (SceneEntity nin : in) {
+//                if (nin.getId().equals(n.getId())) {
+//                    treeGrid.setChecked(true);
+//                }
+//            }
+//            if (n.getParentId() != null) {
+//                treeGrid.setParentId(n.getParentId());
+//            }
+//            nodes.add(treeGrid);
+//        }
+//        return buildTree();
+//    }
+
+}

+ 58 - 0
gis_service/src/main/java/com/gis/service/tree/vo/SceneTree.java

@@ -0,0 +1,58 @@
+package com.gis.service.tree.vo;
+
+import com.alibaba.fastjson.annotation.JSONField;
+import lombok.Data;
+
+import java.util.List;
+
+
+@Data
+public class SceneTree {
+
+    private Long id;
+
+    @JSONField(serialize = false)
+    private String name;
+
+    private String sceneTitle;
+
+    private String sceneCode;
+
+    private Long parentId;
+
+
+    @JSONField(serialize = false)
+    private boolean checked = false;
+
+    @JSONField(serialize = false)
+    private boolean spread = false;
+
+    @JSONField(serialize = false)
+    private String isHeader = "0";
+
+    @JSONField(serialize = false)
+    private String url;
+
+    @JSONField(serialize = false)
+    private String icon;
+
+    @JSONField(serialize = false)
+    private String resourceKey;
+
+    @JSONField(serialize = false)
+    private String resourceType;
+
+    @JSONField(serialize = false)
+    private String order = "1";
+
+    // 子菜单/或按钮
+    private List<SceneTree> children;
+
+    @JSONField(serialize = false)
+    private int level;
+
+    // 默认都没有权限
+//    private boolean authority ;
+
+
+}

+ 31 - 0
gis_web/src/main/java/com/gis/web/controller/AgeController.java

@@ -0,0 +1,31 @@
+package com.gis.web.controller;
+
+import com.gis.common.util.Result;
+import com.gis.service.AgeService;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+import org.springframework.web.multipart.MultipartFile;
+
+/**
+ * Created by owen on 2021/6/22 0022 9:06
+ */
+@Slf4j
+@Api(tags = "四维看看转大场景")
+@RestController
+@RequestMapping("api/age")
+public class AgeController {
+
+    @Autowired
+    AgeService ageService;
+
+    @ApiOperation(value = "上传四维看看完整数据", notes = "必须安指定结构上传,否则上传失败, 场景码(重复加一)")
+    @PostMapping("uploadAge")
+    public Result uploadAge(MultipartFile file){
+
+        return ageService.uploadAge(file);
+
+    }
+}

+ 7 - 0
gis_web/src/main/java/com/gis/web/controller/SceneController.java

@@ -43,6 +43,13 @@ public class SceneController extends BaseController {
     }
 
 
+    @ApiOperation("树场景列表")
+    @PostMapping("listTree")
+    public Result listTree(@RequestBody PageDto param) {
+        return sceneService.listTree(param);
+    }
+
+
     @ApiOperation("场景编辑")
     @PostMapping("edit")
     public Result edit(@Valid @RequestBody SceneDataDto param)  {