ソースを参照

unity上传资料生成 大场景数据

wuweihao 3 年 前
コミット
8c557979e4

+ 9 - 2
README.md

@@ -1,4 +1,11 @@
 # model_beijing_gallery
 
-北京虚拟美术馆
-模型上传功能
+北京虚拟美术馆
+模型上传功能
+
+#sit
+    部署在 (需要使用模型算法)
+     doc:http://192.168.0.44:8002/doc.html
+     
+
+     

+ 74 - 0
gis_application/src/main/resources/application-dev.properties

@@ -0,0 +1,74 @@
+
+#DB
+spring.datasource.type=com.alibaba.druid.pool.DruidDataSource
+spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
+spring.datasource.druid.username=root
+spring.datasource.druid.url=jdbc:mysql://8.135.106.227:3306/${project.en}?serverTimezone=GMT%2B8&useUnicode=true&characterEncoding=utf8&characterSetResults=utf8
+spring.datasource.druid.password=4dkk2021testproject%
+
+
+# \u521D\u59CB\u8FDE\u63A5\u6570
+spring.datasource.druid.initial-size=5
+# \u6700\u5C0F\u8FDE\u63A5\u6C60\u6570\u91CF
+spring.datasource.druid.min-idle=10
+# \u6700\u5927\u8FDE\u63A5\u6C60\u6570\u91CF
+spring.datasource.druid.max-active=20
+# \u914D\u7F6E\u83B7\u53D6\u8FDE\u63A5\u7B49\u5F85\u8D85\u65F6\u7684\u65F6\u95F4
+spring.datasource.druid.max-wait=60000
+# \u914D\u7F6E\u95F4\u9694\u591A\u4E45\u624D\u8FDB\u884C\u4E00\u6B21\u68C0\u6D4B\uFF0C\u68C0\u6D4B\u9700\u8981\u5173\u95ED\u7684\u7A7A\u95F2\u8FDE\u63A5\uFF0C\u5355\u4F4D\u662F\u6BEB\u79D2
+spring.datasource.druid.time-between-eviction-runs-millis=60000
+# \u914D\u7F6E\u4E00\u4E2A\u8FDE\u63A5\u5728\u6C60\u4E2D\u6700\u5C0F\u751F\u5B58\u7684\u65F6\u95F4\uFF0C\u5355\u4F4D\u662F\u6BEB\u79D2
+spring.datasource.druid.min-evictable-idle-time-millis=30000
+# \u914D\u7F6E\u4E00\u4E2A\u8FDE\u63A5\u5728\u6C60\u4E2D\u6700\u5927\u751F\u5B58\u7684\u65F6\u95F4\uFF0C\u5355\u4F4D\u662F\u6BEB\u79D2
+spring.datasource.druid.max-evictable-idle-time-millis=90000
+# \u914D\u7F6E\u68C0\u6D4B\u8FDE\u63A5\u662F\u5426\u6709\u6548
+spring.datasource.druid.validation-query=SELECT 1 FROM DUAL
+spring.datasource.druid.test-while-idle=true
+spring.datasource.druid.test-on-borrow=false
+spring.datasource.druid.test-on-return=false
+spring.datasource.druid.web-stat-filter.enabled=true
+spring.datasource.druid.stat-view-servlet.enabled=true
+
+
+# Redis\u6570\u636E\u5E93\u7D22\u5F15\uFF08\u9ED8\u8BA4\u4E3A0\uFF09
+spring.redis.database=0
+spring.redis.host=127.0.0.1
+spring.redis.port=6379
+spring.redis.password=
+# \u8FDE\u63A5\u8D85\u65F6\u65F6\u95F4 \u5355\u4F4D ms\uFF08\u6BEB\u79D2\uFF09
+spring.redis.timeout=3000ms
+# \u8FDE\u63A5\u6C60\u4E2D\u7684\u6700\u5927\u7A7A\u95F2\u8FDE\u63A5\uFF0C\u9ED8\u8BA4\u503C\u4E5F\u662F8\u3002
+spring.redis.jedis.pool.max-idle=8
+#\u8FDE\u63A5\u6C60\u4E2D\u7684\u6700\u5C0F\u7A7A\u95F2\u8FDE\u63A5\uFF0C\u9ED8\u8BA4\u503C\u4E5F\u662F0\u3002
+spring.redis.jedis.pool.min-idle=0
+# \u5982\u679C\u8D4B\u503C\u4E3A-1\uFF0C\u5219\u8868\u793A\u4E0D\u9650\u5236\uFF1B\u5982\u679Cpool\u5DF2\u7ECF\u5206\u914D\u4E86maxActive\u4E2Ajedis\u5B9E\u4F8B\uFF0C\u5219\u6B64\u65F6pool\u7684\u72B6\u6001\u4E3Aexhausted(\u8017\u5C3D)\u3002
+spring.redis.jedis.pool.max-active=8
+# \u7B49\u5F85\u53EF\u7528\u8FDE\u63A5\u7684\u6700\u5927\u65F6\u95F4\uFF0C\u5355\u4F4D\u6BEB\u79D2\uFF0C\u9ED8\u8BA4\u503C\u4E3A-1\uFF0C\u8868\u793A\u6C38\u4E0D\u8D85\u65F6\u3002\u5982\u679C\u8D85\u8FC7\u7B49\u5F85\u65F6\u95F4\uFF0C\u5219\u76F4\u63A5\u629B\u51FAJedisConnectionException
+spring.redis.jedis.pool.max-wait=-1ms
+
+
+#log
+logging.file.path=E:/log/${project.en}_log
+logging.config=classpath:logback-spring.xml
+logging.level.com.gis=debug
+
+# file info
+server.file.path=E:\\data\\${project.en}_data
+server.domain=127.0.0.1:${server.port}
+
+#
+spring.mvc.static-path-pattern=/**
+### \u5339\u914D\u8DEF\u5F84\uFF0C \u6CE8\u610Ffile\u540E\u9762\u7684/ \uFF0Cwindows:\\  , linxu:\u5168\u8DEF\u5F84, \u4E0D\u9700\u8981\u7279\u522B\u52A0\u659C\u6760
+spring.resources.static-locations=file:\\${server.file.path}
+
+# swagger2 \u8BBE\u7F6E\u5168\u5C40\u5B57\u4F53\u683C\u5F0F\u4E3Autf-8
+swagger.package=com.gis
+swagger.title=${project.sc}-dev
+swagger.description=${swagger.title}
+swagger.version=1.0
+
+
+
+
+
+

+ 77 - 0
gis_application/src/main/resources/application-sit.properties

@@ -0,0 +1,77 @@
+
+#DB
+spring.datasource.type=com.alibaba.druid.pool.DruidDataSource
+spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
+spring.datasource.druid.username=root
+spring.datasource.druid.url=jdbc:mysql://8.135.106.227:3306/${project.en}?serverTimezone=GMT%2B8&useUnicode=true&characterEncoding=utf8&characterSetResults=utf8
+spring.datasource.druid.password=4dkk2021testproject%
+
+
+# \u521D\u59CB\u8FDE\u63A5\u6570
+spring.datasource.druid.initial-size=5
+# \u6700\u5C0F\u8FDE\u63A5\u6C60\u6570\u91CF
+spring.datasource.druid.min-idle=10
+# \u6700\u5927\u8FDE\u63A5\u6C60\u6570\u91CF
+spring.datasource.druid.max-active=20
+# \u914D\u7F6E\u83B7\u53D6\u8FDE\u63A5\u7B49\u5F85\u8D85\u65F6\u7684\u65F6\u95F4
+spring.datasource.druid.max-wait=60000
+# \u914D\u7F6E\u95F4\u9694\u591A\u4E45\u624D\u8FDB\u884C\u4E00\u6B21\u68C0\u6D4B\uFF0C\u68C0\u6D4B\u9700\u8981\u5173\u95ED\u7684\u7A7A\u95F2\u8FDE\u63A5\uFF0C\u5355\u4F4D\u662F\u6BEB\u79D2
+spring.datasource.druid.time-between-eviction-runs-millis=60000
+# \u914D\u7F6E\u4E00\u4E2A\u8FDE\u63A5\u5728\u6C60\u4E2D\u6700\u5C0F\u751F\u5B58\u7684\u65F6\u95F4\uFF0C\u5355\u4F4D\u662F\u6BEB\u79D2
+spring.datasource.druid.min-evictable-idle-time-millis=30000
+# \u914D\u7F6E\u4E00\u4E2A\u8FDE\u63A5\u5728\u6C60\u4E2D\u6700\u5927\u751F\u5B58\u7684\u65F6\u95F4\uFF0C\u5355\u4F4D\u662F\u6BEB\u79D2
+spring.datasource.druid.max-evictable-idle-time-millis=90000
+# \u914D\u7F6E\u68C0\u6D4B\u8FDE\u63A5\u662F\u5426\u6709\u6548
+spring.datasource.druid.validation-query=SELECT 1 FROM DUAL
+spring.datasource.druid.test-while-idle=true
+spring.datasource.druid.test-on-borrow=false
+spring.datasource.druid.test-on-return=false
+spring.datasource.druid.web-stat-filter.enabled=true
+spring.datasource.druid.stat-view-servlet.enabled=true
+
+
+# Redis\u6570\u636E\u5E93\u7D22\u5F15\uFF08\u9ED8\u8BA4\u4E3A0\uFF09
+spring.redis.database=0
+spring.redis.host=127.0.0.1
+spring.redis.port=6379
+spring.redis.password=
+# \u8FDE\u63A5\u8D85\u65F6\u65F6\u95F4 \u5355\u4F4D ms\uFF08\u6BEB\u79D2\uFF09
+spring.redis.timeout=3000ms
+# \u8FDE\u63A5\u6C60\u4E2D\u7684\u6700\u5927\u7A7A\u95F2\u8FDE\u63A5\uFF0C\u9ED8\u8BA4\u503C\u4E5F\u662F8\u3002
+spring.redis.jedis.pool.max-idle=8
+#\u8FDE\u63A5\u6C60\u4E2D\u7684\u6700\u5C0F\u7A7A\u95F2\u8FDE\u63A5\uFF0C\u9ED8\u8BA4\u503C\u4E5F\u662F0\u3002
+spring.redis.jedis.pool.min-idle=0
+# \u5982\u679C\u8D4B\u503C\u4E3A-1\uFF0C\u5219\u8868\u793A\u4E0D\u9650\u5236\uFF1B\u5982\u679Cpool\u5DF2\u7ECF\u5206\u914D\u4E86maxActive\u4E2Ajedis\u5B9E\u4F8B\uFF0C\u5219\u6B64\u65F6pool\u7684\u72B6\u6001\u4E3Aexhausted(\u8017\u5C3D)\u3002
+spring.redis.jedis.pool.max-active=8
+# \u7B49\u5F85\u53EF\u7528\u8FDE\u63A5\u7684\u6700\u5927\u65F6\u95F4\uFF0C\u5355\u4F4D\u6BEB\u79D2\uFF0C\u9ED8\u8BA4\u503C\u4E3A-1\uFF0C\u8868\u793A\u6C38\u4E0D\u8D85\u65F6\u3002\u5982\u679C\u8D85\u8FC7\u7B49\u5F85\u65F6\u95F4\uFF0C\u5219\u76F4\u63A5\u629B\u51FAJedisConnectionException
+spring.redis.jedis.pool.max-wait=-1ms
+
+
+#log
+logging.file.path=/root/log/${project.en}_log
+logging.config=classpath:logback-spring.xml
+logging.level.com.gis=debug
+
+# file info
+server.file.path=/root/data/${project.en}_data
+server.domain=127.0.0.1:${server.port}
+
+# url info
+#server.url.prefix=/data/
+#spring.mvc.static-path-pattern=/${server.url.prefix}/**
+#
+spring.mvc.static-path-pattern=/**
+### \u5339\u914D\u8DEF\u5F84\uFF0C \u6CE8\u610Ffile\u540E\u9762\u7684/ \uFF0Cwindows:\\  , linxu:\u5168\u8DEF\u5F84, \u4E0D\u9700\u8981\u7279\u522B\u52A0\u659C\u6760
+spring.resources.static-locations=file:${server.file.path}
+
+# swagger2 \u8BBE\u7F6E\u5168\u5C40\u5B57\u4F53\u683C\u5F0F\u4E3Autf-8
+swagger.package=com.gis
+swagger.title=${project.sc}-sit
+swagger.description=${swagger.title}
+swagger.version=1.0
+
+
+
+
+
+

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

@@ -0,0 +1,46 @@
+server.port=8002
+
+spring.profiles.active=dev
+
+# \u9879\u76EE\u540D\u79F0
+project.en=model_beijing_gallery
+project.sc=\u5317\u4EAC\u865A\u62DF\u7F8E\u672F\u9986
+# redis token \u524D\u7F00
+redis.prefix=${project.en}_token_
+
+# \u5141\u8BB8\u4E0A\u4F20\u6587\u4EF6\u540E\u7F00
+server.file.allow=.jpg,.gif,.png,.ico,.bmp,.jpeg,.zip,.zp,.rar,.mp3,.mp4,.avi,.mov,.flv,.3gp,.rmvb,.4dage,.wav,.wma,.m4a,.obj,.pdf,.audio,.ppt,.pptx,.xls,.doc,.docx,.txt
+
+
+
+# \u8BBF\u95EE\u9759\u6001\u8D44\u6E90\u8BBE\u7F6E
+spring.resources.static-locations=classpath:templates/,classpath:static/,classpath:web/
+
+#\u4E0A\u4F20\u6587\u4EF6\u5927\u5C0F
+spring.servlet.multipart.enabled=true
+spring.servlet.multipart.max-file-size=2048MB
+spring.servlet.multipart.max-request-size=2048MB
+
+
+
+#\u914D\u7F6E\u81EA\u52A8\u8BC6\u522B\u5B57\u6BB5\u8F6C\u6362
+mybatis.configuration.mapUnderscoreToCamelCase=true
+mapper.identity=MYSQL
+mapper.mappers=tk.mybatis.mapper.common.Mapper
+#pager
+pagehelper.helper-dialect=mysql
+pagehelper.params=count=countSql
+pagehelper.reasonable=false
+pagehelper.support-methods-arguments=true
+
+
+
+
+
+
+
+
+
+
+
+

+ 17 - 0
gis_application/src/main/resources/data/images.json

@@ -0,0 +1,17 @@
+
+{
+"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": "update",
+"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
+}

+ 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": "false",
+  "hotImageScale": "false",
+  "hideFloorMarker": "false",
+  "hideMouseMarker": "false",
+  "floorMarkerColor": "#4bcdfc",
+  "mouseMarkerColor": "#4bcdfc",
+  "momentTour": "walk",
+  "showHotListSta": "false",
+  "hotIconScale": "1",
+  "supportsVR": "false",
+  "weixinDesc": ""
+}

+ 102 - 0
gis_application/src/main/resources/db/sys_resource.sql

@@ -0,0 +1,102 @@
+/*
+ Navicat Premium Data Transfer
+
+ Source Server         : 8.135.106.227_项目_sit
+ Source Server Type    : MySQL
+ Source Server Version : 50733
+ Source Host           : 8.135.106.227:3306
+ Source Schema         : army_beijing_hospital
+
+ Target Server Type    : MySQL
+ Target Server Version : 50733
+ File Encoding         : 65001
+
+ Date: 22/02/2022 17:49:03
+*/
+
+SET NAMES utf8mb4;
+SET FOREIGN_KEY_CHECKS = 0;
+
+-- ----------------------------
+-- Table structure for sys_resource
+-- ----------------------------
+DROP TABLE IF EXISTS `sys_resource`;
+CREATE TABLE `sys_resource`  (
+  `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT 'id',
+  `create_time` datetime(0) NULL DEFAULT CURRENT_TIMESTAMP(0) COMMENT '创建时间',
+  `update_time` datetime(0) NULL DEFAULT CURRENT_TIMESTAMP(0) COMMENT '更新时间',
+  `name` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '资源名称',
+  `resource_type` enum('menu','button') CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '资源类型',
+  `resource_key` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '资源key',
+  `sort` int(6) NULL DEFAULT NULL COMMENT '排序',
+  `parent_id` bigint(20) NULL DEFAULT NULL COMMENT '父资源id',
+  `is_delete` int(1) NULL DEFAULT 0 COMMENT '是否删除,0:可用, 1:删除',
+  `url` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '资源地址',
+  `description` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '资源描述',
+  PRIMARY KEY (`id`) USING BTREE,
+  INDEX `FKf5ra2gn0xedeida2op8097sr5`(`parent_id`) USING BTREE,
+  CONSTRAINT `FKf5ra2gn0xedeida2op8097sr5` FOREIGN KEY (`parent_id`) REFERENCES `sys_resource` (`id`) ON DELETE RESTRICT ON UPDATE RESTRICT
+) ENGINE = InnoDB AUTO_INCREMENT = 812 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = '资源表' ROW_FORMAT = DYNAMIC;
+
+-- ----------------------------
+-- Records of sys_resource
+-- ----------------------------
+INSERT INTO `sys_resource` VALUES (100, '2021-07-21 10:05:26', '2021-07-21 10:05:26', '史馆场景管理', 'menu', 'scene', 100, NULL, 0, NULL, NULL);
+INSERT INTO `sys_resource` VALUES (101, '2021-07-21 10:05:26', '2021-07-21 10:05:26', '查看', 'button', 'scene:detail', 101, 100, 1, NULL, NULL);
+INSERT INTO `sys_resource` VALUES (102, '2021-07-21 10:05:26', '2021-07-21 10:05:26', '编辑', 'button', 'scene:edit', 102, 100, 0, NULL, NULL);
+INSERT INTO `sys_resource` VALUES (103, '2021-07-21 10:05:27', '2021-07-21 10:05:27', '删除', 'button', 'scene:remove', 103, 100, 1, NULL, NULL);
+
+INSERT INTO `sys_resource` VALUES (200, '2021-07-21 10:05:27', '2021-07-21 10:05:27', '精品典藏管理', 'menu', 'goods', 200, NULL, 0, NULL, NULL);
+INSERT INTO `sys_resource` VALUES (210, '2021-07-21 10:05:27', '2021-07-21 10:05:27', '模型管理', 'menu', 'goods:model', 210, 200, 0, NULL, NULL);
+INSERT INTO `sys_resource` VALUES (212, '2021-07-21 10:05:27', '2021-07-21 10:05:27', '编辑', 'button', 'goods:edit', 212, 210, 0, NULL, NULL);
+INSERT INTO `sys_resource` VALUES (213, '2021-07-21 10:05:27', '2021-07-21 10:05:27', '删除', 'button', 'good:remove', 213, 210, 0, NULL, NULL);
+INSERT INTO `sys_resource` VALUES (215, '2021-07-21 10:05:27', '2021-07-21 10:05:27', '查看', 'button', 'goods:detail', 215, 210, 1, NULL, NULL);
+INSERT INTO `sys_resource` VALUES (216, '2021-07-21 10:05:27', '2021-07-21 10:05:27', '是否显示', 'button', 'goods:display', 216, 210, 0, NULL, NULL);
+INSERT INTO `sys_resource` VALUES (217, '2021-08-19 21:48:01', '2021-08-19 21:48:01', '新增', 'button', 'goods:edit', 217, 210, 0, NULL, NULL);
+
+INSERT INTO `sys_resource` VALUES (220, '2021-07-21 10:05:27', '2021-07-21 10:05:27', '视频管理', 'menu', 'goods:video', 220, 200, 0, NULL, NULL);
+INSERT INTO `sys_resource` VALUES (222, '2021-07-21 10:05:27', '2021-07-21 10:05:27', '编辑', 'button', 'goods:edit', 222, 220, 0, NULL, NULL);
+INSERT INTO `sys_resource` VALUES (223, '2021-07-21 10:05:27', '2021-07-21 10:05:27', '删除', 'button', 'goods:remove', 223, 220, 0, NULL, NULL);
+INSERT INTO `sys_resource` VALUES (225, '2021-07-21 10:05:27', '2021-07-21 10:05:27', '查看', 'button', 'goods:detail', 225, 220, 1, NULL, NULL);
+INSERT INTO `sys_resource` VALUES (226, '2021-07-21 10:05:27', '2021-07-21 10:05:27', '是否显示', 'button', 'goods:display', 226, 220, 0, NULL, NULL);
+INSERT INTO `sys_resource` VALUES (227, '2021-08-19 21:50:48', '2021-08-19 21:50:48', '新增', 'button', 'goods:edit', 227, 220, 0, NULL, NULL);
+
+INSERT INTO `sys_resource` VALUES (230, '2021-07-21 10:05:27', '2021-07-21 10:05:27', '图片管理', 'menu', 'goods:img', 230, 200, 0, NULL, NULL);
+INSERT INTO `sys_resource` VALUES (231, '2021-07-21 10:05:27', '2021-07-21 10:05:27', '提交', 'button', 'goods:edit', 231, 230, 1, NULL, NULL);
+INSERT INTO `sys_resource` VALUES (232, '2021-07-21 10:05:27', '2021-07-21 10:05:27', '编辑', 'button', 'goods:edit', 232, 230, 0, NULL, NULL);
+INSERT INTO `sys_resource` VALUES (233, '2021-07-21 10:05:27', '2021-07-21 10:05:27', '删除', 'button', 'goods:remove', 233, 230, 0, NULL, NULL);
+INSERT INTO `sys_resource` VALUES (235, '2021-07-21 10:05:27', '2021-07-21 10:05:27', '查看', 'button', 'goods:detail', 235, 230, 1, NULL, NULL);
+INSERT INTO `sys_resource` VALUES (236, '2021-07-21 10:05:27', '2021-07-21 10:05:27', '是否显示', 'button', 'goods:display', 236, 230, 0, NULL, NULL);
+INSERT INTO `sys_resource` VALUES (237, '2021-08-19 21:51:17', '2021-08-19 21:51:17', '新增', 'button', 'goods:edit', 237, 230, 0, NULL, NULL);
+
+
+
+INSERT INTO `sys_resource` VALUES (500, '2021-07-21 10:05:28', '2021-07-21 10:05:28', '互动模块管理', 'menu', 'comment&barrage', 500, NULL, 0, NULL, NULL);
+INSERT INTO `sys_resource` VALUES (510, '2021-07-21 10:05:28', '2021-07-21 10:05:28', '留言管理', 'menu', 'comment', 510, 500, 0, NULL, NULL);
+INSERT INTO `sys_resource` VALUES (511, '2021-07-21 10:05:28', '2021-07-21 10:05:28', '删除', 'button', 'comment:remove', 511, 510, 0, NULL, NULL);
+INSERT INTO `sys_resource` VALUES (512, '2021-07-21 10:05:28', '2021-07-21 10:05:28', '查看', 'button', 'comment:detail', 512, 510, 1, NULL, NULL);
+INSERT INTO `sys_resource` VALUES (513, '2021-07-21 10:05:28', '2021-07-21 10:05:28', '是否显示', 'button', 'comment:display', 513, 510, 0, NULL, NULL);
+INSERT INTO `sys_resource` VALUES (518, '2022-02-22 17:46:41', '2022-02-22 17:46:41', '导出', 'button', 'comment:export', NULL, 510, 1, NULL, NULL);
+
+INSERT INTO `sys_resource` VALUES (520, '2021-07-21 10:05:28', '2021-07-21 10:05:28', '弹幕管理', 'menu', 'barrage', 520, 500, 0, NULL, NULL);
+INSERT INTO `sys_resource` VALUES (521, '2021-07-21 10:05:28', '2021-07-21 10:05:28', '删除', 'button', 'barrage:remove', 521, 520, 0, NULL, NULL);
+INSERT INTO `sys_resource` VALUES (522, '2021-07-21 10:05:28', '2021-07-21 10:05:28', '查看', 'button', 'barrage:detail', 522, 520, 1, NULL, NULL);
+INSERT INTO `sys_resource` VALUES (523, '2021-07-21 10:05:28', '2021-07-21 10:05:28', '是否显示', 'button', 'barrage:display', 523, 520, 0, NULL, NULL);
+INSERT INTO `sys_resource` VALUES (528, '2022-02-22 17:47:07', '2022-02-22 17:47:07', '导出', 'button', 'barrage:export', NULL, 528, 1, NULL, NULL);
+
+
+INSERT INTO `sys_resource` VALUES (600, '2021-08-26 19:29:41', '2021-08-26 19:29:41', '用户管理', 'menu', 'sys:user', 600, NULL, 0, NULL, NULL);
+INSERT INTO `sys_resource` VALUES (610, '2021-08-26 19:30:48', '2021-08-26 19:30:48', '新增', 'button', 'sys:user:edit', 610, 600, 0, NULL, NULL);
+INSERT INTO `sys_resource` VALUES (611, '2021-08-26 19:31:28', '2021-08-26 19:31:28', '编辑', 'button', 'sys:user:edit', 611, 600, 0, NULL, NULL);
+INSERT INTO `sys_resource` VALUES (612, '2021-08-26 19:32:51', '2021-08-26 19:32:51', '是否启用', 'button', 'sys:user:display', 612, 600, 0, NULL, NULL);
+INSERT INTO `sys_resource` VALUES (613, '2021-08-26 19:33:32', '2021-08-26 19:33:32', '删除', 'button', 'sys:user:remove', 613, 600, 0, NULL, NULL);
+INSERT INTO `sys_resource` VALUES (700, '2021-08-26 19:34:24', '2021-08-26 19:34:24', '角色权限管理', 'menu', 'sys:role', 700, NULL, 0, NULL, NULL);
+INSERT INTO `sys_resource` VALUES (710, '2021-08-26 19:35:00', '2021-08-26 19:35:00', '新增', 'button', 'sys:role:edit', 710, 700, 0, NULL, NULL);
+INSERT INTO `sys_resource` VALUES (711, '2021-08-26 19:35:29', '2021-08-26 19:35:29', '编辑', 'button', 'sys:role:edit', 711, 700, 0, NULL, NULL);
+INSERT INTO `sys_resource` VALUES (712, '2021-08-26 19:36:07', '2021-08-26 19:36:07', '是否启用', 'button', 'sys:role:display', 712, 700, 0, NULL, NULL);
+INSERT INTO `sys_resource` VALUES (713, '2021-08-26 19:36:36', '2021-08-26 19:36:36', '删除', 'button', 'sys:role:remove', 713, 700, 0, NULL, NULL);
+INSERT INTO `sys_resource` VALUES (714, '2021-08-26 19:38:03', '2021-08-26 19:38:03', '权限设置', 'button', 'sys:role:auth', 714, 700, 0, NULL, NULL);
+INSERT INTO `sys_resource` VALUES (800, '2021-08-26 19:38:40', '2021-08-26 19:38:40', '操作日志', 'menu', 'sys:log', 800, NULL, 0, NULL, NULL);
+INSERT INTO `sys_resource` VALUES (811, '2022-01-18 09:46:29', '2022-01-18 09:46:29', '查看', 'button', 'sys:log:view', NULL, 800, 0, NULL, NULL);
+
+SET FOREIGN_KEY_CHECKS = 1;

+ 156 - 0
gis_application/src/main/resources/logback-spring.xml

@@ -0,0 +1,156 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<configuration scan="true" scanPeriod="60 seconds" debug="false">
+    <property name="LOG_MAX_HISTORY" value="180"/>
+    <springProperty scope="context" name="LOG_PATH" source="logging.path"/>
+
+    <!-- 控制台输出 -->
+    <appender name="console" class="ch.qos.logback.core.ConsoleAppender">
+        <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
+            <!--格式化输出:%d表示日期,%thread表示线程名,%-5level:级别从左显示5个字符宽度%msg:日志消息,%n是换行符 -->
+            <pattern>${LOG_PATH}/%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %X{TRACE_ID} %-5level %logger{50} - %msg%n</pattern>
+            <!--<charset>utf-8</charset>-->
+        </encoder>
+    </appender>
+    <!-- 按照每天生成日志文件:主项目日志 -->
+    <appender name="file.all" class="ch.qos.logback.core.rolling.RollingFileAppender">
+        <!-- 追加日志到原文件结尾 -->
+        <Prudent>true</Prudent>
+        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
+            <!--日志文件输出的文件名 -->
+            <FileNamePattern>${LOG_PATH}/%d{yyyy-MM-dd}.%i.log</FileNamePattern>
+            <MaxHistory>${LOG_MAX_HISTORY}</MaxHistory>
+            <timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
+                <!-- 除按日志记录之外,还配置了日志文件不能超过10M(默认),若超过10M,日志文件会以索引0开始, -->
+                <maxFileSize>10MB</maxFileSize>
+            </timeBasedFileNamingAndTriggeringPolicy>
+        </rollingPolicy>
+        <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
+            <!--格式化输出:%d表示日期,%thread表示线程名,%-5level:级别从左显示5个字符宽度%msg:日志消息,%n是换行符 -->
+            <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %X{TRACE_ID} %-5level %logger{500} - %msg%n</pattern>
+            <!--<charset>utf-8</charset>-->
+        </encoder>
+    </appender>
+
+    <!--info日志统一输出到这里-->
+    <appender name="file.info" class="ch.qos.logback.core.rolling.RollingFileAppender">
+        <Prudent>true</Prudent>
+        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
+            <!--日志文件输出的文件名 每小时生成日志文件 -->
+            <FileNamePattern>${LOG_PATH}/%d{yyyy-MM-dd}/info/console-info.%d{yyyy-MM-dd-HH}.%i.log</FileNamePattern>
+            <MaxHistory>${LOG_MAX_HISTORY}</MaxHistory>
+            <timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
+                <!-- 除按日志记录之外,还配置了日志文件不能超过10M(默认),若超过10M,日志文件会以索引0开始, -->
+                <maxFileSize>10MB</maxFileSize>
+            </timeBasedFileNamingAndTriggeringPolicy>
+        </rollingPolicy>
+        <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
+            <!--格式化输出:%d表示日期,%thread表示线程名,%-5level:级别从左显示5个字符宽度 %method 方法名  %L 行数 %msg:日志消息,%n是换行符-->
+            <pattern> %d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %X{TRACE_ID} %-5level %logger{56}.%method:%L - %msg%n</pattern>
+            <!--<charset>utf-8</charset>-->
+        </encoder>
+        <!-- 此日志文件只记录info级别的 -->
+        <filter class="ch.qos.logback.classic.filter.LevelFilter">
+            <level>INFO</level>
+            <onMatch>ACCEPT</onMatch>
+            <onMismatch>DENY</onMismatch>
+        </filter>
+    </appender>
+
+    <!--错误日志统一输出到这里-->
+    <appender name="file.error" class="ch.qos.logback.core.rolling.RollingFileAppender">
+        <Prudent>true</Prudent>
+        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
+            <!--日志文件输出的文件名-->
+            <FileNamePattern>${LOG_PATH}/%d{yyyy-MM-dd}/error/console-error.%d{yyyy-MM-dd-HH}.%i.log</FileNamePattern>
+            <!--日志文件保留天数-->
+            <MaxHistory>${LOG_MAX_HISTORY}</MaxHistory>
+            <timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
+                <!-- 除按日志记录之外,还配置了日志文件不能超过10M(默认),若超过10M,日志文件会以索引0开始, -->
+                <maxFileSize>10MB</maxFileSize>
+            </timeBasedFileNamingAndTriggeringPolicy>
+        </rollingPolicy>
+        <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
+            <!--格式化输出:%d表示日期,%thread表示线程名,%-5level:级别从左显示5个字符宽度 %method 方法名  %L 行数 %msg:日志消息,%n是换行符-->
+            <pattern> %d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %X{TRACE_ID} %-5level %logger{56}.%method:%L - %msg%n</pattern>
+            <!--<charset>utf-8</charset>-->
+        </encoder>
+        <!-- 此日志文件只记录error级别的 -->
+        <filter class="ch.qos.logback.classic.filter.LevelFilter">
+            <level>ERROR</level>
+            <onMatch>ACCEPT</onMatch>
+            <onMismatch>DENY</onMismatch>
+        </filter>
+    </appender>
+
+    <!--warn日志统一输出到这里-->
+    <appender name="file.warn" class="ch.qos.logback.core.rolling.RollingFileAppender">
+        <Prudent>true</Prudent>
+        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
+            <!--日志文件输出的文件名 按小时生成日志-->
+            <FileNamePattern>${LOG_PATH}/%d{yyyy-MM-dd}/warn/console-warn.%d{yyyy-MM-dd-HH}.%i.log</FileNamePattern>
+            <!--日志文件保留天数-->
+            <MaxHistory>${LOG_MAX_HISTORY}</MaxHistory>
+            <timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
+                <!-- 除按日志记录之外,还配置了日志文件不能超过10M(默认),若超过10M,日志文件会以索引0开始, -->
+                <maxFileSize>10MB</maxFileSize>
+            </timeBasedFileNamingAndTriggeringPolicy>
+        </rollingPolicy>
+        <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
+            <!--格式化输出:%d表示日期,%thread表示线程名,%-5level:级别从左显示5个字符宽度 %method 方法名  %L 行数 %msg:日志消息,%n是换行符-->
+            <pattern> %d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %X{TRACE_ID} %-5level %logger{56}.%method:%L - %msg%n</pattern>
+            <!--<charset>utf-8</charset>-->
+        </encoder>
+        <!-- 此日志文件只记录warn级别的 -->
+        <filter class="ch.qos.logback.classic.filter.LevelFilter">
+            <level>WARN</level>
+            <onMatch>ACCEPT</onMatch>
+            <onMismatch>DENY</onMismatch>
+        </filter>
+    </appender>
+
+    <!--debug级别日志统一输出到这里-->
+    <appender name="file.debug" class="ch.qos.logback.core.rolling.RollingFileAppender">
+        <Prudent>true</Prudent>
+        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
+            <!--日志文件输出的文件名 按小时生成日志-->
+            <FileNamePattern>${LOG_PATH}/%d{yyyy-MM-dd}/debug/console-debug.%d{yyyy-MM-dd-HH}.%i.log</FileNamePattern>
+            <!--日志文件保留天数-->
+            <MaxHistory>${LOG_MAX_HISTORY}</MaxHistory>
+            <!-- 除按日志记录之外,还配置了日志文件不能超过5M,若超过5M,日志文件会以索引0开始,命名日志文件,例如console-debug.2018-08-24-09.1.log -->
+            <timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
+                <maxFileSize>10MB</maxFileSize>
+            </timeBasedFileNamingAndTriggeringPolicy>
+        </rollingPolicy>
+        <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
+            <!--格式化输出:%d表示日期,%thread表示线程名,%-5level:级别从左显示5个字符宽度 %method 方法名  %L 行数 %msg:日志消息,%n是换行符-->
+            <pattern> %d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %X{TRACE_ID} %-5level %logger{56}.%method:%L - %msg%n</pattern>
+            <!--<charset>utf-8</charset>-->
+        </encoder>
+        <!-- 此日志文件只记录debug级别的 -->
+        <filter class="ch.qos.logback.classic.filter.LevelFilter">
+            <level>DEBUG</level>
+            <onMatch>ACCEPT</onMatch>
+            <onMismatch>DENY </onMismatch>
+        </filter>
+    </appender>
+
+    <!-- 不丢失日志.默认的,如果队列的80%已满,则会丢弃TRACT、DEBUG、INFO级别的日志 -->
+    <appender name="file.async" class="ch.qos.logback.classic.AsyncAppender">
+        <discardingThreshold>0</discardingThreshold>
+        <queueSize>256</queueSize>
+        <includeCallerData>true</includeCallerData>
+        <appender-ref ref="file.all" />
+    </appender>
+
+    <!--  日志输出级别 -->
+    <!-- TRACE\DEBUG\INFO\WARN\ERROR\FATAL\OFF -->
+    <root level="INFO">
+        <appender-ref ref="console" />
+        <appender-ref ref="file.async"/>
+        <appender-ref ref="file.error" />
+        <appender-ref ref="file.info" />
+        <appender-ref ref="file.debug" />
+        <appender-ref ref="file.warn" />
+    </root>
+
+</configuration>

+ 48 - 0
gis_common/src/main/java/com/gis/common/constant/ErrorEnum.java

@@ -0,0 +1,48 @@
+package com.gis.common.constant;
+
+/**
+ * Created by owen on 2022/3/10 0010 14:47
+ */
+public enum ErrorEnum {
+
+    FAILURE_CODE_3001(3001, "缺少必要参数"),
+    FAILURE_CODE_3002(3002, "访问异常!"),
+    FAILURE_CODE_3003(3003, "非法访问!"),
+    FAILURE_CODE_3004(3004, "用户未登录"),
+    FAILURE_CODE_3005(3005, "验证码已过期"),
+    FAILURE_CODE_3006(3006, "验证码错误"),
+    FAILURE_CODE_3007(3007, "昵称已存在"),
+    FAILURE_CODE_3008(3008, "该手机已被注册"),
+    FAILURE_CODE_3009(3009, "两次输入的密码不一致"),
+    FAILURE_CODE_3010(3010, "昵称长度错误"),
+    FAILURE_CODE_3011(3011, "密码需要包含英文大小写、数字,长度8-16字符"),
+    FAILURE_CODE_3012(3012, "昵称包含敏感词"),
+    FAILURE_CODE_3013(3013, "手机号码格式错误"),
+    FAILURE_CODE_3014(3014, "账号或密码不正确"),
+    FAILURE_CODE_3015(3015, "用户不存在"),
+    FAILURE_CODE_3016(3016, "登录失败,账号无权访问"),
+    FAILURE_CODE_3017(3017, "空文件"),
+    FAILURE_CODE_3018(3018, "需要上传或使用的文件不存在"),
+
+    ;
+
+    private Integer code;
+    private String message;
+
+    private ErrorEnum(Integer code, String message) {
+        this.code = code;
+        this.message = message;
+    }
+
+    public Integer code() {
+        return code;
+    }
+
+    public String message() {
+        return message;
+    }
+
+    public String formatMessage(Object... args){
+        return String.format(message, args);
+    }
+}

+ 22 - 0
gis_common/src/main/java/com/gis/common/util/RandomUtils.java

@@ -0,0 +1,22 @@
+package com.gis.common.util;
+
+import cn.hutool.core.util.RandomUtil;
+
+/**
+ * Created by owen on 2020/4/26 0026 10:07
+ *
+ *
+ */
+public class RandomUtils {
+
+    public static String randomString(int length){
+        String baseString = "abcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
+        return RandomUtil.randomString(baseString, length);
+    }
+
+    public static String randomString(int length, String prefix){
+        String s = randomString(length);
+        return prefix+"_"+s;
+    }
+
+}

+ 57 - 0
gis_scene/pom.xml

@@ -0,0 +1,57 @@
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+    <parent>
+        <artifactId>model_beijing_gallery</artifactId>
+        <groupId>com.gis</groupId>
+        <version>1.0.0</version>
+    </parent>
+
+    <modelVersion>4.0.0</modelVersion>
+    <artifactId>gis_scene</artifactId>
+    <packaging>jar</packaging>
+
+    <dependencies>
+        <dependency>
+            <groupId>com.gis</groupId>
+            <artifactId>gis_common</artifactId>
+        </dependency>
+
+
+        <!-- 针对proto包 转换格式用-->
+        <dependency>
+            <groupId>com.google.protobuf</groupId>
+            <artifactId>protobuf-java</artifactId>
+            <version>3.2.0</version>
+        </dependency>
+        <dependency>
+            <groupId>com.googlecode.protobuf-java-format</groupId>
+            <artifactId>protobuf-java-format</artifactId>
+            <version>1.4</version>
+        </dependency>
+
+        <dependency>
+            <groupId>org.codehaus.jackson</groupId>
+            <artifactId>jackson-mapper-asl</artifactId>
+            <version>1.9.11</version>
+        </dependency>
+
+        <dependency>
+            <groupId>org.codehaus.jackson</groupId>
+            <artifactId>jackson-smile</artifactId>
+            <version>1.9.12</version>
+        </dependency>
+
+        <dependency>
+            <groupId>com.belerweb</groupId>
+            <artifactId>pinyin4j</artifactId>
+            <version>2.5.1</version>
+        </dependency>
+
+    </dependencies>
+
+
+
+
+
+</project>

+ 41 - 0
gis_scene/remark.md

@@ -0,0 +1,41 @@
+# 上传数据生成大场景数据
+    someData.json -> vision_version -> 控制版本前端加载图片版本
+    
+    untiy上传资料:
+    panorama 
+    dacf7dfa24ae47fab8fcebfe4dc41ab9_50k_texture_jpg_high
+    extras
+    vision.txt
+    
+    
+    算法生成资料
+    pan
+    results
+ 
+ http://192.168.0.44:8101/SuperTwo/index.html?m=ar_jvWeBmEgQ
+ 
+  data文件夹
+  
+         --ar_WTJ1ooJDD 场景码
+             - xxx_50k_texture_jpg(文通)
+             - vision.txt(文通)
+             
+             - vision.modeldata(java通过是vision.txt转的)
+             - data2.js(java生成的空json)
+             - someData.json(java生成)
+             - xxx_50k.dam(java生成)
+             
+             
+             
+  数据处理逻辑:
+     	1. 文通部门上传文件到指定目录
+     	2. 调用算法切图(slice_skybox)         (算法处理)
+     	3. 调用算法将obj_to_txt                  (算法处理)
+     	4. 转换前端需要的文件
+     		4.1 对算法生成的result文件夹的upload.json进程校验,处理相应逻辑
+     			4.1.1 图片归类到相应文件夹      (java处理)
+     			4.1.2 将modeldata.txt转xxx.dam    (java处理)
+     		4.2 vision.txt转vision.modeldata   (java处理) 【模型和相机点位的数据(vision.modeldata,******.dam)】
+     		4.3 生成data2.js                     (java处理)
+     		4.4 创建someData.json                 (java处理)          
+   

+ 85 - 0
gis_scene/src/main/java/com/gis/scene/controller/UnityController.java

@@ -0,0 +1,85 @@
+package com.gis.scene.controller;
+
+import com.gis.common.constant.ConfigConstant;
+import com.gis.common.util.RandomUtils;
+import com.gis.common.util.Result;
+import com.gis.scene.service.UnityService;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiImplicitParam;
+import io.swagger.annotations.ApiImplicitParams;
+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;
+
+import java.util.Map;
+
+
+/**
+ * Created by owen on 20202/3/8 0008 9:54
+ */
+@Slf4j
+@Api(tags = "模型资料管理")
+@RestController
+@RequestMapping("cms/unity")
+public class UnityController {
+
+    @Autowired
+    UnityService entityService;
+
+    @Autowired
+    ConfigConstant configConstant;
+
+
+
+    /**
+     *  map的key值是json参数,value是文件
+     * @param param
+     * @param sceneCode
+     * @return
+     */
+    @ApiOperation(value = "box视频上传", notes = "自定义上传位置,文件名需要验证中文字符")
+    @PostMapping("uploadBox")
+    @ApiImplicitParams({
+            @ApiImplicitParam(name = "sceneCode", value = "场景码", required = true),
+            @ApiImplicitParam(name = "param", value = "Map传参, key:路径,value:文件", required = true),
+    })
+
+    public Result uploadBox(@RequestParam Map<String, MultipartFile> param, String sceneCode) {
+        return entityService.uploadBox(param, sceneCode);
+    }
+
+    /**
+     * 创建场景
+     * @param param
+     * @param sceneTitle
+     * @param sceneCode
+     * @return
+     * @throws Exception
+     */
+    @ApiOperation(value = "Map表单上传多文件,指定保存路径,需要用postman测试", notes = "自定义上传位置,文件名需要验证中文字符")
+    @PostMapping("uploads")
+    @ApiImplicitParams({
+            @ApiImplicitParam(name = "sceneCode", value = "场景码", required = true),
+            @ApiImplicitParam(name = "sceneTitle", value = "场景名称", required = true),
+            @ApiImplicitParam(name = "param", value = "Map传参, key:路径,value:文件", required = true),
+    })
+    public Result uploads(@RequestParam Map<String, MultipartFile> param, String sceneTitle, String sceneCode) throws Exception {
+
+
+
+
+        return entityService.uploads(param, sceneTitle, sceneCode);
+    }
+
+    @ApiOperation("获取场景码")
+    @GetMapping("getSceneCode")
+    public Result getSceneCode() {
+        String sceneCode = RandomUtils.randomString(9, "vr");
+        return Result.success((Object) sceneCode);
+    }
+
+
+
+}

+ 34 - 0
gis_scene/src/main/java/com/gis/scene/service/SceneService.java

@@ -0,0 +1,34 @@
+package com.gis.scene.service;
+
+
+import com.gis.common.base.entity.dto.PageDto;
+import com.gis.common.base.service.IBaseService;
+import com.gis.common.util.Result;
+import com.gis.scene.entity.dto.RoamViableDto;
+import com.gis.scene.entity.dto.SceneDataDto;
+import com.gis.scene.entity.po.SceneEntity;
+import org.springframework.web.multipart.MultipartFile;
+
+
+/**
+ * Created by owen on 2020/3/11 0011 16:14
+ */
+public interface SceneService extends IBaseService<SceneEntity, Long> {
+
+
+    SceneEntity findBySceneCode(String m);
+
+    Result<SceneEntity> search(PageDto param);
+
+    Result roamViable(RoamViableDto param) throws Exception;
+
+    Result edit(SceneDataDto param);
+
+    Result display(Long id);
+
+    Result addStar(Long id);
+
+    Result addVisit(Long id);
+
+    Result upload(MultipartFile file, String sceneCode);
+}

+ 19 - 0
gis_scene/src/main/java/com/gis/scene/service/UnityService.java

@@ -0,0 +1,19 @@
+package com.gis.scene.service;
+
+
+import com.gis.common.util.Result;
+import org.springframework.web.multipart.MultipartFile;
+
+import java.util.Map;
+
+
+/**
+ * Created by owen on 2020/3/11 0011 16:14
+ */
+public interface UnityService  {
+
+
+    Result uploadBox(Map<String, MultipartFile> param, String sceneCode);
+
+    Result uploads(Map<String, MultipartFile> param, String sceneTitle, String sceneCode) throws Exception;
+}

+ 426 - 0
gis_scene/src/main/java/com/gis/scene/service/impl/SceneServiceImpl.java

@@ -0,0 +1,426 @@
+package com.gis.scene.service.impl;
+
+import cn.hutool.core.io.FileUtil;
+import com.alibaba.fastjson.JSON;
+import com.alibaba.fastjson.JSONArray;
+import com.alibaba.fastjson.JSONObject;
+import com.alibaba.fastjson.serializer.SerializerFeature;
+import com.gis.common.base.entity.dto.PageDto;
+import com.gis.common.base.mapper.IBaseMapper;
+import com.gis.common.base.service.impl.IBaseServiceImpl;
+import com.gis.common.util.Result;
+import com.gis.scene.entity.dto.RoamViableDto;
+import com.gis.scene.entity.dto.SceneDataDto;
+import com.gis.scene.entity.po.SceneEntity;
+import com.gis.scene.mapper.SceneMapper;
+import com.gis.scene.proto.util.ConvertUtils;
+import com.gis.scene.service.SceneService;
+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 org.springframework.web.multipart.MultipartFile;
+
+import java.util.Map;
+import java.util.Set;
+
+
+/**
+ * Created by owen on 2020/3/11 0011 16:16
+ */
+@Slf4j
+@Service
+public class SceneServiceImpl extends IBaseServiceImpl<SceneEntity, Long> implements SceneService {
+
+    @Autowired
+    private SceneMapper entityMapper;
+
+    @Override
+    public IBaseMapper<SceneEntity, Long> getBaseMapper() {
+        return this.entityMapper;
+    }
+
+
+    @Override
+    public SceneEntity findBySceneCode(String m) {
+        return entityMapper.findBySceneCode(m);
+    }
+
+    @Override
+    public Result<SceneEntity> search(PageDto param) {
+        startPage(param);
+        PageInfo<SceneEntity> page = new PageInfo<>(entityMapper.search(param));
+        return Result.success(page);
+    }
+
+    /**
+     * 漫游可行
+     */
+    @Override
+    public Result roamViable(RoamViableDto param) throws Exception {
+        String sceneCode = param.getSceneCode();
+        SceneEntity entity = entityMapper.findBySceneCode(param.getSceneCode());
+        if (entity == null) {
+            log.error("场景不存在:{}", sceneCode);
+            return Result.failure("场景不存在");
+        }
+
+
+        // 1. 从oss下载vision.modeldata
+        String visionModelDataName = "vision.modeldata";
+        // 注意网络下载会有缓存,必须加时间戳
+//        log.info("网络下载文件地址: {}", urlPath);
+//        String localBasePath = FILE_PATH + sceneCode;
+        String localBasePath = configConstant.serverBasePath +"/data/" + sceneCode;
+
+        // 2. 将vision.modeldata 转 vision.json
+        String visionModelDataPath = localBasePath + "/" + visionModelDataName;
+        if (!FileUtil.exist(visionModelDataPath)) {
+            log.error("vision.modeldata不存在 : {}", visionModelDataPath);
+            return Result.failure("vision.modeldata不存在");
+        }
+//        log.info(visionModelDataName+ "下载完成");
+
+
+        String visionJsonPath = localBasePath + "/vision.json";
+        ConvertUtils.convertVisionModelDataToTxt(visionModelDataPath, visionJsonPath);
+        if (!FileUtil.exist(visionJsonPath)) {
+            log.error("vision.json不存在 : {}", visionJsonPath);
+            return Result.failure("vision.modeldata不存在");
+        }
+
+        // 3. 编辑新数据到vision.json
+        JSONArray inputDates = JSONObject.parseArray(param.getData());
+
+        JSONObject visionJson = JSONObject.parseObject(FileUtil.readUtf8String(visionJsonPath));
+        JSONArray sweepLocations = visionJson.getJSONArray("sweepLocations");
+
+        for (int i = 0; i < sweepLocations.size(); i++) {
+            JSONObject pano = sweepLocations.getJSONObject(i);
+
+            for (int j = 0; j < inputDates.size(); j++) {
+                JSONObject jo = inputDates.getJSONObject(j);
+                String panoID = jo.getString("panoID");
+                JSONArray visibles3 = jo.getJSONArray("visibles3");
+
+                // 去掉uuid 的“-”
+                String uuid = pano.getString("uuid");
+                String s = StringUtils.replaceAll(uuid, "-", "");
+                if (s.equals(panoID)) {
+                    log.info("uuid: {}, panoID: {}", uuid, panoID);
+                    pano.put("visibles", visibles3);
+                    log.info("visibles: {},visibles3:{}", pano.get("visibles"), visibles3);
+                }
+            }
+        }
+
+
+        // 删除旧vision.json,vision.modeldata
+        FileUtil.del(visionJsonPath);
+        FileUtil.del(visionModelDataPath);
+
+        // 写入新vision.json
+        FileUtil.writeUtf8String(visionJson.toJSONString(), visionJsonPath);
+        if (!FileUtil.exist(visionJsonPath)) {
+            log.error("new vision.json不存在");
+        }
+
+        log.info( "新vision.json创建完成 :{}", visionJsonPath);
+
+
+
+
+        // 4. 将vision.json转vision.modeldata
+        ConvertUtils.convertTxtToVisionModelData(visionJsonPath, visionModelDataPath);
+
+        // 5. 将新的vision.modeldata上传到oss
+        if (!FileUtil.exist(visionModelDataPath)) {
+            log.error("vision.modeldata不存在");
+        }
+        log.info("新" + visionModelDataName+ "创建完成 :{}", visionModelDataPath);
+
+
+        return Result.success();
+    }
+
+    @Override
+    public Result edit(SceneDataDto param) {
+        String sceneCode = param.getSceneCode();
+        SceneEntity entity = this.findBySceneCode(param.getSceneCode());
+        if (entity == null) {
+            log.error("场景不存在 : {}", sceneCode);
+            return Result.failure("场景不存在");
+        }
+
+        String basePath = configConstant.serverBasePath +"/data/" + sceneCode;
+
+
+        // 处理someData.json
+
+//        String someDataPath = entity.getPath() + "/someData.json";
+        String someDataPath = basePath + "/someData.json";
+        if (!FileUtil.isFile(someDataPath)) {
+            log.error("someData.json文件不存在");
+            return Result.failure("someData.json文件不存在");
+        }
+
+        // 读取someDataJson
+        String someData = FileUtil.readUtf8String(someDataPath);
+        JSONObject someDataJson = JSONObject.parseObject(someData);
+
+
+
+        String info = param.getInfo();
+        String guides = param.getGuides();
+        JSONArray guidesArray = new JSONArray();
+        if (guides != null) {
+            guidesArray = JSONObject.parseArray(guides);
+
+        }
+
+
+        if (info != null) {
+            JSONObject infoJson = JSONObject.parseObject(info);
+
+            // 处理model
+            JSONObject model = someDataJson.getJSONObject("model");
+            if (model != null) {
+                if (guidesArray != null) {
+                    model.put("images", guidesArray);
+                }
+
+            }
+
+            // 更新someDataJson
+            someDataJson.put("model", model);
+
+            // info信息添加到someDataJson最外层
+            Set<String> infoKey = infoJson.keySet();
+            for (String key : infoKey) {
+
+                someDataJson.put(key, infoJson.get(key));
+            }
+
+            // 删除旧someDataJson
+            FileUtil.del(someDataPath);
+            // 写入新someDataJson
+            FileUtil.writeUtf8String(someDataJson.toJSONString(), someDataPath);
+            log.info("someData.json写入完成");
+        }
+
+        // 处理data2.js
+        String data2Path = basePath + "/data2.js";
+        boolean file = FileUtil.isFile(data2Path);
+        if (!file) {
+            log.error("data2.js文件不存在");
+            return Result.failure("data2.js文件不存在");
+        }
+
+        String data2 = FileUtil.readUtf8String(data2Path);
+        JSONObject data2Json = JSONObject.parseObject(data2);
+
+        String tourAudio = param.getTourAudio();
+        if (tourAudio != null) {
+            data2Json.put("tourAudio", JSONObject.parseObject(tourAudio));
+        } else {
+            data2Json.put("tourAudio", new JSONObject());
+        }
+
+        // overlays是数组
+        String overlays = param.getOverlays();
+        if (overlays != null) {
+            data2Json.put("overlays", JSONObject.parseArray(overlays));
+        } else {
+            data2Json.put("overlays", new JSONArray());
+        }
+
+        // 处理guidesArray,将scan_id的值作为key, value:  time":40000
+        JSONObject audioJson = new JSONObject();
+        JSONObject timeJson = new JSONObject();
+        timeJson.put("time", 40000);
+        if (guidesArray != null) {
+
+            // 将旧的audio字段删除
+            data2Json.remove("audio");
+
+            for (int i = 0; i < guidesArray.size() ; i++) {
+                JSONObject metadata = guidesArray.getJSONObject(i).getJSONObject("metadata");
+                if (metadata != null) {
+                    String scanId = metadata.getString("scan_id");
+                    if (scanId == null) {
+                        log.error("guides.metadata.scan_id为空: {}", i);
+                        return Result.failure("guides.metadata.scan_id为空: " + i);
+                    }
+                    // Fastjson-fastjson中$ref对象重复引用问题,拿不到想要的效果
+                    audioJson.put(scanId, JSON.toJSONString(timeJson, SerializerFeature.DisableCircularReferenceDetect));
+
+                }
+            }
+
+            // 新增audio
+            data2Json.put("audio", audioJson);
+        }
+
+
+        // host在data2.js、data.js都需要处理
+        String hots = param.getHots();
+        log.info("input hots: {}", hots);
+        if (hots != null) {
+            // 获取所有key
+            JSONObject hotJson = JSONObject.parseObject(hots);
+
+            Set<String> strings = hotJson.keySet();
+            for (String key: strings) {
+                JSONObject subJson = hotJson.getJSONObject(key);
+
+                // 2021.04.02 处理link
+                String link = getLink(subJson, key);
+
+                // 将link 添加进去
+                subJson.put("link", link);
+            }
+            data2Json.put("hots", hotJson);
+        } else {
+            data2Json.put("hots", new JSONObject());
+        }
+
+
+        // 删除旧data2.js
+        FileUtil.del(data2Path);
+
+
+        // 写入新data2.js
+        FileUtil.writeUtf8String(data2Json.toJSONString(), data2Path);
+        log.info("新data2.js写入完成");
+
+
+        //处理data.js 文件
+        editDataJs(entity, hots);
+
+        return Result.success();
+    }
+
+    @Override
+    public Result display(Long id) {
+        SceneEntity entity = findById(id);
+        if (entity == null) {
+            return Result.failure("场景不存在, id: " + id);
+        }
+        // 需求:只有一个是可用;先禁用,再启用
+        entityMapper.setDisable();
+        entityMapper.setDisplay(id);
+        return Result.success();
+    }
+
+    @Override
+    public Result addStar(Long id) {
+        entityMapper.addStar(id);
+        return Result.success();
+    }
+
+    @Override
+    public Result addVisit(Long id) {
+        entityMapper.addVisit(id);
+        return Result.success();
+    }
+
+    @Override
+    public Result upload(MultipartFile file, String sceneCode) {
+        if (file == null) {
+            log.error("文件不能为空");
+            return Result.failure("文件不能为空");
+        }
+
+        SceneEntity entity = this.findBySceneCode(sceneCode);
+        if (entity == null) {
+            log.error("场景不存在: {}", sceneCode);
+            return Result.failure("场景不存在");
+        }
+
+        Map<String, Object> uploadMap = fileUtils.uploadMap(file, "/data/" + sceneCode + "/edit/hot", false);
+
+
+        return Result.success(uploadMap.get("filePath"));
+    }
+
+    /**
+     * 2021.04.02 处理infoAttribute的m_title
+     * String url  = "https://www.4dmodel.com/SuperTwo/hot_online/index.html?m=" + key;
+     * String url  = SERVER_DOMAIN + "edit-backstage/hot_online/index.html?m=" + key;
+     * m_title:[]
+     * 有值: link = "/edit-backstage/hot_online1/index.html?m=" + key
+     * 无值: link = "/edit-backstage/hot_online/index.html?m=" + key
+     */
+    private String getLink(JSONObject param, String key){
+//        JSONObject infoAttribute = param.getJSONObject("infoAttribute");
+        // m_title可能会没有这个属性key, 需要判断
+//        JSONArray m_title = infoAttribute.getJSONArray("m_title");
+//        String url  = "/edit-backstage/hot_online/index.html#/?m=" + key;
+//        if (m_title != null && m_title.size() > 0){
+//            url  = "/edit-backstage/hot_online1/index.html#/?m=" + key;
+//        }
+        String url  = "/edit-backstage/hot_online1/index.html#/?m=" + key;
+        return url;
+    }
+
+    /**
+     * 处理data.js 文件
+     */
+    private void editDataJs(SceneEntity entity, String hots )  {
+
+        // 因为data.js只是热点信息,所以直接创建上传oss
+        JSONObject dataJsJson = new JSONObject();
+        if (hots != null) {
+            dataJsJson = JSONObject.parseObject(hots);
+
+            Set<String> strings = dataJsJson.keySet();
+            for (String key: strings) {
+                JSONObject subJson = dataJsJson.getJSONObject(key);
+                JSONObject infoAttribute = subJson.getJSONObject("infoAttribute");
+                if (infoAttribute != null) {
+                    Set<String> infoKey = infoAttribute.keySet();
+
+                    for (String s: infoKey) {
+                        Object val = null;
+                        // 添加到第一层, 空值不添加
+                        if ("images".equals(s) || "styleImg".equals(s) || "model".equals(s) || "video".equals(s) || "iframe".equals(s)) {
+                            JSONArray jsonArray = infoAttribute.getJSONArray(s);
+                            if (jsonArray.size() == 0) {
+                                continue;
+                            }
+                            val = jsonArray;
+
+                        } else {
+                            String a = infoAttribute.getString(s);
+                            if (StringUtils.isBlank(a)){
+                                continue;
+                            }
+                            val = a;
+                        }
+
+
+                        subJson.put(s, val);
+                    }
+
+                }
+
+                // 删除infoAttribute
+                subJson.remove("infoAttribute");
+
+            }
+
+        }
+
+        log.info("out data.js : {}", dataJsJson);
+        String basePath = configConstant.serverBasePath +"/data/" + entity.getSceneCode();
+
+        String dataPath = basePath + "/hot/js/data.js";
+        FileUtil.writeUtf8String(dataJsJson.toJSONString(), dataPath);
+
+        log.info("新data.js写入完成: {}", dataPath);
+
+
+    }
+}

+ 351 - 0
gis_scene/src/main/java/com/gis/scene/service/impl/UnityServiceImpl.java

@@ -0,0 +1,351 @@
+package com.gis.scene.service.impl;
+
+import cn.hutool.core.io.FileUtil;
+import cn.hutool.core.lang.Validator;
+import com.alibaba.fastjson.JSONArray;
+import com.alibaba.fastjson.JSONObject;
+import com.gis.common.base.exception.BaseRuntimeException;
+import com.gis.common.constant.ConfigConstant;
+import com.gis.common.util.FileUtils;
+import com.gis.common.util.Result;
+import com.gis.scene.entity.po.SceneEntity;
+import com.gis.scene.proto.constant.ConstantCmd;
+import com.gis.scene.proto.constant.ConstantFileName;
+import com.gis.scene.proto.util.CreateObjUtil;
+import com.gis.scene.service.SceneService;
+import com.gis.scene.service.UnityService;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import org.springframework.util.ResourceUtils;
+import org.springframework.web.multipart.MultipartFile;
+
+import java.io.File;
+import java.io.IOException;
+import java.time.LocalDateTime;
+import java.util.Map;
+
+
+/**
+ * Created by owen on 2020/3/11 0011 16:16
+ *
+ * 场景放在:根目录/data/场景码
+ */
+@Slf4j
+@Service
+public class UnityServiceImpl implements UnityService {
+
+    @Autowired
+    SceneService sceneService;
+
+    @Autowired
+    ConfigConstant configConstant;
+
+
+    @Override
+    public Result uploadBox(Map<String, MultipartFile> param, String sceneCode) {
+
+        SceneEntity entity = sceneService.findBySceneCode(sceneCode);
+        if (entity == null) {
+            log.error("对象不存在:{}", sceneCode);
+            return Result.failure("场景码不存在");
+        }
+
+        // 保存位置(箭头函数传参,需要定义final, 使用时需要赋值使用)
+//        String basePath = entity.getPath();
+        String basePath = configConstant.serverBasePath + "/data/" + sceneCode;
+        final String saveBasePath = basePath + "/boxVideo/";
+
+        // box视频信息
+        JSONArray overlaysArray = new JSONArray();
+
+        param.forEach((key, file)->{
+
+            if (StringUtils.isBlank(key)) {
+                log.error("key值不能为空");
+                throw new BaseRuntimeException("key值不能为空");
+            }
+
+            if (file == null) {
+                log.error("文件不能为空");
+                throw new BaseRuntimeException("文件不能为空");
+            }
+
+            String fileName = file.getOriginalFilename();
+
+            if (Validator.hasChinese(fileName)) {
+                log.error("文件名不能有中文字符: {}", fileName);
+                throw new BaseRuntimeException("文件名不能有中文字符");
+            }
+
+
+
+            JSONObject keyJson = JSONObject.parseObject(key);
+
+            // 给相对路径,tomcat配置静态资源让前端读取
+            // http://192.168.0.44:8101/data/ar_I4Ef2SS4y/boxVideo/20180201_101827.mp4
+            String boxVideoPath = "/data/" + entity.getSceneCode()+ "/boxVideo/" + fileName;
+//            log.info("boxVideoPath: {}", boxVideoPath);
+
+            // 添加视频参数到overlayJaon
+            keyJson.put("file", boxVideoPath);
+            overlaysArray.add(keyJson);
+
+
+            // final值需要赋值使用
+            String filePath = saveBasePath;
+
+            filePath += fileName;
+            log.info("filePath: {}", filePath);
+            try {
+//                FileUtils.upload(file, filePath);
+                FileUtil.writeFromStream(file.getInputStream(), filePath);
+            } catch (IOException e) {
+                e.printStackTrace();
+            }
+
+        });
+
+        JSONObject dataJson = new JSONObject();
+        dataJson.put("overlays", overlaysArray);
+
+        // 创建data2.js文件
+        String saveDataJsonPath = basePath + "/data2.js";
+        log.info("data2.js path :{}", saveDataJsonPath);
+        FileUtil.writeUtf8String(dataJson.toJSONString(), saveDataJsonPath);
+        log.info("data2.js创建完成");
+
+        return Result.success(entity.getWebSite());
+    }
+
+    /***
+     *
+     * @param param 传入地址包含场景码
+     * @param sceneTitle
+     * @param sceneCode
+     * @return
+     * @throws Exception
+     */
+    @Override
+    public Result uploads(Map<String, MultipartFile> param, String sceneTitle, String sceneCode) throws Exception {
+        if (StringUtils.isBlank(sceneCode)){
+            log.error("场景码不能为空");
+            return Result.failure("场景码不能为空");
+        }
+
+        if (StringUtils.isBlank(sceneTitle)){
+            log.error("场景标题不能为空");
+            return Result.failure("场景标题不能为空");
+        }
+
+        SceneEntity entity = sceneService.findBySceneCode(sceneCode);
+        if (entity != null) {
+            log.error("场景码已存在,请更换新场景码: {}", sceneCode);
+            return Result.failure("场景码已存在,请更换新场景码");
+        }
+
+
+        String basePath = configConstant.serverBasePath +"/data/";
+
+        // 传入地址包含场景码
+        param.forEach((path, file)->{
+
+            if (StringUtils.isBlank(path)) {
+                log.error("保存路径不能为空");
+                throw new BaseRuntimeException("保存路径不能为空");
+            }
+
+            if (file == null) {
+                log.error("文件不能为空");
+                throw new BaseRuntimeException("文件为空");
+            }
+            String fileName = file.getOriginalFilename();
+            if (Validator.hasChinese(fileName)) {
+                log.error("文件名不能有中文字符: {}", fileName);
+                throw new BaseRuntimeException("文件名不能有中文字符:" + fileName);
+            }
+
+            path = basePath + path;
+            log.info("savePath: {}", path);
+            try {
+                FileUtil.writeFromStream(file.getInputStream(), path);
+            } catch (IOException e) {
+                e.printStackTrace();
+            }
+
+        });
+
+
+
+        entity = new SceneEntity();
+        entity.setSceneCode(sceneCode);
+        entity.setPath("/data/" + sceneCode);
+        entity.setSceneTitle(sceneTitle);
+
+        entity.setUpdateTime(LocalDateTime.now());
+
+
+
+
+        // 调用算法切图片转换
+        String rootPath = basePath + sceneCode;
+//        String cmd = ConstantCmd.SLICE_SKYBOX + entity.getPath();
+        String cmd = ConstantCmd.SLICE_SKYBOX + rootPath;
+        log.info("cmd:{}", cmd);
+        CreateObjUtil.callshell(cmd);
+        log.info("算法切片完成");
+
+
+        // 调用算法将obj转txt
+//        String objCmd = ConstantCmd.OBJ_TO_TXT + entity.getPath();
+        String objCmd = ConstantCmd.OBJ_TO_TXT + rootPath;
+        log.info("objCmd:{}", objCmd);
+        CreateObjUtil.callshell(objCmd);
+        log.info("算法obj转txt完成");
+
+
+        // 转换文件
+//        convert(entity.getPath(), sceneCode, sceneTitle);
+        convert(rootPath, sceneCode, sceneTitle);
+        log.info("文件转换完成");
+
+        // 场景url
+//        String webSite = SERVER_DOMAIN + "SuperTwo/index.html?m=" + sceneCode;
+//        String webSite = configConstant.serverBasePath + "/SuperTwo/index.html?m=" + sceneCode;
+        String webSite = "/SuperTwo/index.html?m=" + sceneCode;
+        log.info("webSite: {}", webSite);
+
+
+        entity.setWebSite(webSite);
+        sceneService.save(entity);
+        return Result.success(entity.getWebSite());
+    }
+
+
+    /**
+     * 文件转换
+     * @param sceneCode
+     * @throws Exception
+     */
+    private void convert(String basePath, String sceneCode, String sceneTitle) throws Exception {
+
+        // 将result文件夹的upload.json是否存在,并处理业务逻辑
+        checkUploadJson(basePath);
+
+
+        if(!FileUtil.exist(basePath+"/vision.txt")){
+            log.error("文件不存在: " + basePath+"/vision.txt");
+            Result.failure("文件不存在: " + basePath+"/vision.txt");
+        }
+
+        // 2.vision.txt转vision.modeldata
+        CreateObjUtil.convertTxtToVisionmodeldata(basePath+"/vision.txt", basePath+"/vision.modeldata");
+        log.info("vision.modeldata转换完成");
+
+        // 3. 生成一个空的data2.js, 里面是一个空的json
+        FileUtil.writeUtf8String("{}",basePath+"/data2.js");
+        log.info("data2.js创建完成");
+
+        // 4. 创建someData.json, 修改sid值为场景码目录
+        createSomeData(basePath, sceneCode, sceneTitle);
+
+
+    }
+
+    /**
+     * 检查upload.json文件是否存在,执行业务逻辑
+     */
+    private static void checkUploadJson(String basePath) throws Exception {
+        String uploadJsonPath = basePath + "/results/upload.json";
+//        String uploadJsonPath = "F:\\test\\army\\upload.json";
+        boolean isUploadJsonPath = FileUtil.isFile(uploadJsonPath);
+        if (!isUploadJsonPath) {
+            log.error("算法的upload.json不存在");
+            throw new BaseRuntimeException(5000, "算法的upload.json不存在");
+
+        }
+        // 判断upload.json文件是否都存在
+        String os = FileUtil.readUtf8String(uploadJsonPath);
+        JSONObject imageObject = JSONObject.parseObject(os);
+
+        // json数组
+        JSONArray jsonArray = imageObject.getJSONArray("upload");
+        for (int i = 0; i < jsonArray.size(); i++) {
+            JSONObject jsonObject = jsonArray.getJSONObject(i);
+            String fileName = jsonObject.getString("file");
+            String filePath = basePath + "/results/" + fileName;
+
+            boolean isFilePath = FileUtil.isFile(filePath);
+            if (!isFilePath) {
+                log.error("算法的upload.json数据文件:  {}", filePath );
+                throw new BaseRuntimeException(5000, "算法的upload.json数据文件不存在");
+
+            }
+
+            String suffix = StringUtils.substringAfterLast(filePath, ".");
+            // 把图片复制到指定目录(dacf7dfa24ae47fab8fcebfe4dc41ab9_50k_texture_jpg_high)
+            if ("jpg".equals(suffix)) {
+                FileUtil.copy(filePath, basePath+"/" + ConstantFileName.modelUUID+"_50k_texture_jpg_high/" + fileName, true);
+            }
+
+            // 将modeldata.txt转xxx.dam
+            if ("txt".equals(suffix)) {
+                CreateObjUtil.convertTxtToDam(filePath, basePath+"/" + ConstantFileName.modelUUID+"_50k.dam");
+                log.info("dam转换完成");
+
+            }
+
+        }
+    }
+
+
+    /**
+     * 创建someData.json
+     */
+    private  void createSomeData(String basePath, String sceneCode, String sceneTitle) throws IOException {
+//        String path = ResourceUtils.getURL("classpath:").getPath();
+//        path = path + "data/someData.json";
+        String path = configConstant.serverBasePath + "/baseData/someData.json";
+        log.info("path: {}", path);
+        String os = FileUtil.readUtf8String(path);
+        JSONObject jsonObject = JSONObject.parseObject(os);
+        JSONObject model = jsonObject.getJSONObject("model");
+
+
+        // 更新images json
+        JSONArray imagesJson = updateImagesData(sceneCode);
+        model.put("images", imagesJson);
+
+        // 修改sid值
+        model.put("sid", sceneCode);
+        model.put("name", sceneTitle);
+
+        // 更新json
+        jsonObject.put("model", model);
+
+
+        FileUtil.writeUtf8String(jsonObject.toJSONString(), basePath+"/someData.json");
+
+        log.info("someData.json创建完成");
+
+    }
+
+
+    /**
+     * 创建images.json
+     * 如果数据格式有变动,要作出响应的修改
+     */
+    private  JSONArray updateImagesData(String sceneCode) throws IOException {
+//        String resourceUrl = FileUtils.getResourceUrl("data/images.json");
+        String resourceUrl = configConstant.serverBasePath + "/baseData/someData.json";
+        String os = FileUtil.readUtf8String(resourceUrl);
+        JSONObject imageObject = JSONObject.parseObject(os);
+        imageObject.put("sid", sceneCode);
+
+        JSONArray imagesArray = new JSONArray();
+        imagesArray.set(0, imageObject);
+
+        return imagesArray;
+    }
+}

+ 244 - 0
pom.xml

@@ -0,0 +1,244 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+  <modelVersion>4.0.0</modelVersion>
+
+  <groupId>com.gis</groupId>
+  <artifactId>model_beijing_gallery</artifactId>
+  <version>1.0.0</version>
+  <packaging>pom</packaging>
+
+  <parent>
+    <groupId>org.springframework.boot</groupId>
+    <artifactId>spring-boot-starter-parent</artifactId>
+    <version>2.3.4.RELEASE</version>
+    <relativePath/> <!-- lookup parent from repository -->
+  </parent>
+
+  <modules>
+    <module>gis_common</module>
+    <module>gis_admin</module>
+    <module>gis_application</module>
+    <module>gis_scene</module>
+    <module>gis_cms</module>
+  </modules>
+
+
+
+  <properties>
+    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+    <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
+    <java.version>1.8</java.version>
+    <spring.boot.version>2.3.4.RELEASE</spring.boot.version>
+    <gis.version>1.0.0</gis.version>
+    <druid.version>1.1.14</druid.version>
+    <hutool.version>5.3.3</hutool.version>
+    <poi.version>3.17</poi.version>
+    <lombok.version>1.18.2</lombok.version>
+    <fastjson.version>1.2.75</fastjson.version>
+    <lang3.version>3.7</lang3.version>
+    <knife4j.version>2.0.2</knife4j.version>
+    <mysql.version>8.0.15</mysql.version>
+    <shiro.version>1.7.1</shiro.version>
+    <jwt.version>3.2.0</jwt.version>
+    <jjwt.version>0.6.0</jjwt.version>
+    <aliyun.core.version>4.0.3</aliyun.core.version>
+    <aliyun.dysmsapi.version>1.1.0</aliyun.dysmsapi.version>
+    <aliyun.oss.version>2.5.0</aliyun.oss.version>
+    <!--<mybatis.version>3.5.7</mybatis.version>-->
+    <tk.mybatis.version>2.0.2</tk.mybatis.version>
+    <tk.mapper.version>4.0.3</tk.mapper.version>
+    <pagehelper.version>1.2.5</pagehelper.version>
+  </properties>
+
+
+  <!--dependencyManagement用于管理依赖版本号, 必须写版本号,不然依赖不上-->
+  <dependencyManagement>
+    <dependencies>
+      <!--模块版本管理-->
+
+      <dependency>
+        <groupId>com.gis</groupId>
+        <artifactId>gis_application</artifactId>
+        <version>${gis.version}</version>
+      </dependency>
+
+      <dependency>
+        <groupId>com.gis</groupId>
+        <artifactId>gis_common</artifactId>
+        <version>${gis.version}</version>
+      </dependency>
+
+      <dependency>
+        <groupId>com.gis</groupId>
+        <artifactId>gis_admin</artifactId>
+        <version>${gis.version}</version>
+      </dependency>
+
+      <dependency>
+        <groupId>com.gis</groupId>
+        <artifactId>gis_scene</artifactId>
+        <version>${gis.version}</version>
+      </dependency>
+
+      <dependency>
+        <groupId>com.gis</groupId>
+        <artifactId>gis_cms</artifactId>
+        <version>${gis.version}</version>
+      </dependency>
+
+
+
+
+      <!-- springboot -->
+      <dependency>
+        <groupId>org.springframework.boot</groupId>
+        <artifactId>spring-boot-starter-data-jpa</artifactId>
+        <version>${spring.boot.version}</version>
+      </dependency>
+
+      <dependency>
+        <groupId>org.springframework.boot</groupId>
+        <artifactId>spring-boot-starter-web</artifactId>
+        <version>${spring.boot.version}</version>
+      </dependency>
+
+      <dependency>
+        <groupId>org.springframework.boot</groupId>
+        <artifactId>spring-boot-starter-test</artifactId>
+        <scope>test</scope>
+        <version>${spring.boot.version}</version>
+      </dependency>
+
+      <!--springboot中的redis依赖-->
+      <dependency>
+        <groupId>org.springframework.boot</groupId>
+        <artifactId>spring-boot-starter-data-redis</artifactId>
+        <version>${spring.boot.version}</version>
+      </dependency>
+
+      <!--询资料发现从SpringBoot 2.3.0之后放弃了默认对javax.validation 的支持-->
+      <dependency>
+        <groupId>org.springframework.boot</groupId>
+        <artifactId>spring-boot-starter-validation</artifactId>
+        <version>${spring.boot.version}</version>
+      </dependency>
+
+
+      <!-- lombok -->
+      <dependency>
+        <groupId>org.projectlombok</groupId>
+        <artifactId>lombok</artifactId>
+        <version>${lombok.version}</version>
+      </dependency>
+
+      <!-- fastjson -->
+      <dependency>
+        <groupId>com.alibaba</groupId>
+        <artifactId>fastjson</artifactId>
+        <version>${fastjson.version}</version>
+      </dependency>
+
+      <!--阿里数据库连接池 -->
+      <dependency>
+        <groupId>com.alibaba</groupId>
+        <artifactId>druid-spring-boot-starter</artifactId>
+        <version>${druid.version}</version>
+      </dependency>
+
+      <!--aliyun oss-->
+      <dependency>
+        <groupId>com.aliyun.oss</groupId>
+        <artifactId>aliyun-sdk-oss</artifactId>
+        <version>${aliyun.oss.version}</version>
+      </dependency>
+
+
+      <!-- mysql -->
+      <dependency>
+        <groupId>mysql</groupId>
+        <artifactId>mysql-connector-java</artifactId>
+        <version>${mysql.version}</version>
+      </dependency>
+
+      <!-- 工具类 -->
+      <dependency>
+        <groupId>cn.hutool</groupId>
+        <artifactId>hutool-all</artifactId>
+        <version>${hutool.version}</version>
+      </dependency>
+
+      <!--excel 依赖工具包, hutool需要用的-->
+      <dependency>
+        <groupId>org.apache.poi</groupId>
+        <artifactId>poi-ooxml</artifactId>
+        <version>${poi.version}</version>
+      </dependency>
+
+      <!-- StringUtils -->
+      <dependency>
+        <groupId>org.apache.commons</groupId>
+        <artifactId>commons-lang3</artifactId>
+        <version>${lang3.version}</version>
+      </dependency>
+
+      <!-- knife4j aip 包-->
+      <dependency>
+        <groupId>com.github.xiaoymin</groupId>
+        <artifactId>knife4j-spring-boot-starter</artifactId>
+        <version>${knife4j.version}</version>
+      </dependency>
+
+
+      <dependency>
+        <groupId>org.apache.shiro</groupId>
+        <artifactId>shiro-spring-boot-starter</artifactId>
+        <version>${shiro.version}</version>
+      </dependency>
+
+      <!-- jwt -->
+      <dependency>
+        <groupId>com.auth0</groupId>
+        <artifactId>java-jwt</artifactId>
+        <version>${jwt.version}</version>
+      </dependency>
+
+      <dependency>
+        <groupId>io.jsonwebtoken</groupId>
+        <artifactId>jjwt</artifactId>
+        <version>${jjwt.version}</version>
+      </dependency>
+
+
+
+      <!--tk.mybatis 依赖-->
+      <dependency>
+        <groupId>tk.mybatis</groupId>
+        <artifactId>mapper-spring-boot-starter</artifactId>
+        <version>${tk.mybatis.version}</version>
+        <!-- tk.mybatis 跟springboot jap 包冲突-->
+        <exclusions>
+          <exclusion>
+            <groupId>javax.persistence</groupId>
+            <artifactId>persistence-api</artifactId>
+          </exclusion>
+        </exclusions>
+
+      </dependency>
+
+
+
+
+
+
+      <!--分页插件-->
+      <dependency>
+        <groupId>com.github.pagehelper</groupId>
+        <artifactId>pagehelper-spring-boot-starter</artifactId>
+        <version>${pagehelper.version}</version>
+      </dependency>
+
+    </dependencies>
+  </dependencyManagement>
+</project>