whx 5 months ago
parent
commit
ff8c77c9cd
100 changed files with 793 additions and 478 deletions
  1. 359 361
      virgo.wzfrontend/console/src/components/common/upload.vue
  2. 9 2
      virgo.wzfrontend/console/src/components/common/uploadFile.vue
  3. 9 4
      virgo.wzfrontend/console/src/components/system/level/deviceLevel.vue
  4. 77 33
      virgo.wzfrontend/console/src/components/work/common/modelDown.vue
  5. 145 0
      virgo.wzfrontend/console/src/components/work/common/modelForm.vue
  6. 32 15
      virgo.wzfrontend/console/src/components/work/common/threeModel.vue
  7. 12 5
      virgo.wzfrontend/console/src/config/field.js
  8. 11 0
      virgo.wzfrontend/console/src/httpApi/datacenter.js
  9. 58 0
      virgo.wzfrontend/console/src/httpApi/property.js
  10. 30 9
      virgo.wzfrontend/console/src/uitls/threeControls.js
  11. 1 1
      virgo.wzfrontend/src/main/resources/static/console/index.html
  12. 0 0
      virgo.wzfrontend/src/main/resources/static/console/static/css/1888.232edf06.css
  13. 0 1
      virgo.wzfrontend/src/main/resources/static/console/static/css/3065.e719da7b.css
  14. 1 0
      virgo.wzfrontend/src/main/resources/static/console/static/css/3235.5594966c.css
  15. 1 0
      virgo.wzfrontend/src/main/resources/static/console/static/css/3348.5594966c.css
  16. 0 1
      virgo.wzfrontend/src/main/resources/static/console/static/css/843.e719da7b.css
  17. 0 0
      virgo.wzfrontend/src/main/resources/static/console/static/css/8663.232edf06.css
  18. 1 0
      virgo.wzfrontend/src/main/resources/static/console/static/css/8942.fd889f81.css
  19. 0 1
      virgo.wzfrontend/src/main/resources/static/console/static/js/103.174197f0.js
  20. 1 0
      virgo.wzfrontend/src/main/resources/static/console/static/js/103.511e1ba1.js
  21. 1 1
      virgo.wzfrontend/src/main/resources/static/console/static/js/109-legacy.229109ed.js
  22. 1 1
      virgo.wzfrontend/src/main/resources/static/console/static/js/1263-legacy.5fa68517.js
  23. 1 1
      virgo.wzfrontend/src/main/resources/static/console/static/js/1263.9d9fb9c6.js
  24. 0 0
      virgo.wzfrontend/src/main/resources/static/console/static/js/1361.b40c506b.js
  25. 1 1
      virgo.wzfrontend/src/main/resources/static/console/static/js/1471-legacy.cf7f3478.js
  26. 1 1
      virgo.wzfrontend/src/main/resources/static/console/static/js/1471.c3d7d6fa.js
  27. 0 0
      virgo.wzfrontend/src/main/resources/static/console/static/js/1703-legacy.feeb8a75.js
  28. 0 0
      virgo.wzfrontend/src/main/resources/static/console/static/js/1703.6e8204ea.js
  29. 1 1
      virgo.wzfrontend/src/main/resources/static/console/static/js/1821-legacy.491f3664.js
  30. 1 0
      virgo.wzfrontend/src/main/resources/static/console/static/js/1888.8f2fc782.js
  31. 0 1
      virgo.wzfrontend/src/main/resources/static/console/static/js/1888.a4c7c371.js
  32. 1 1
      virgo.wzfrontend/src/main/resources/static/console/static/js/191.0fb32dfc.js
  33. 1 1
      virgo.wzfrontend/src/main/resources/static/console/static/js/2059.03f15905.js
  34. 1 1
      virgo.wzfrontend/src/main/resources/static/console/static/js/2439-legacy.432b096d.js
  35. 1 1
      virgo.wzfrontend/src/main/resources/static/console/static/js/2587-legacy.eda5ba99.js
  36. 1 1
      virgo.wzfrontend/src/main/resources/static/console/static/js/2587.dc5b3ac4.js
  37. 1 0
      virgo.wzfrontend/src/main/resources/static/console/static/js/2610.2300ce1f.js
  38. 0 1
      virgo.wzfrontend/src/main/resources/static/console/static/js/2610.2bec9edb.js
  39. 0 0
      virgo.wzfrontend/src/main/resources/static/console/static/js/2803-legacy.cee27757.js
  40. 0 0
      virgo.wzfrontend/src/main/resources/static/console/static/js/2877-legacy.42676098.js
  41. 1 0
      virgo.wzfrontend/src/main/resources/static/console/static/js/2901-legacy.6345fd4b.js
  42. 0 1
      virgo.wzfrontend/src/main/resources/static/console/static/js/2901-legacy.e3fe6a67.js
  43. 1 0
      virgo.wzfrontend/src/main/resources/static/console/static/js/2901.488bf607.js
  44. 0 1
      virgo.wzfrontend/src/main/resources/static/console/static/js/2901.ca4b0230.js
  45. 1 1
      virgo.wzfrontend/src/main/resources/static/console/static/js/2942.00b5e8d8.js
  46. 0 1
      virgo.wzfrontend/src/main/resources/static/console/static/js/3065.2823a7d9.js
  47. 0 0
      virgo.wzfrontend/src/main/resources/static/console/static/js/3099.9b9195ae.js
  48. 1 0
      virgo.wzfrontend/src/main/resources/static/console/static/js/3235.097d7c0e.js
  49. 1 0
      virgo.wzfrontend/src/main/resources/static/console/static/js/3348-legacy.23718c0f.js
  50. 0 1
      virgo.wzfrontend/src/main/resources/static/console/static/js/3401.1063831c.js
  51. 1 0
      virgo.wzfrontend/src/main/resources/static/console/static/js/3401.34c8c8a0.js
  52. 1 1
      virgo.wzfrontend/src/main/resources/static/console/static/js/3437-legacy.3b072752.js
  53. 1 1
      virgo.wzfrontend/src/main/resources/static/console/static/js/3437.baa73250.js
  54. 0 0
      virgo.wzfrontend/src/main/resources/static/console/static/js/3620-legacy.fc7f229f.js
  55. 0 0
      virgo.wzfrontend/src/main/resources/static/console/static/js/3620.f11f0a7a.js
  56. 0 1
      virgo.wzfrontend/src/main/resources/static/console/static/js/4469-legacy.35cda735.js
  57. 1 0
      virgo.wzfrontend/src/main/resources/static/console/static/js/4469-legacy.ab1fcad8.js
  58. 0 0
      virgo.wzfrontend/src/main/resources/static/console/static/js/4537-legacy.1a839e7f.js
  59. 1 0
      virgo.wzfrontend/src/main/resources/static/console/static/js/4767.9b91fcd1.js
  60. 0 1
      virgo.wzfrontend/src/main/resources/static/console/static/js/4767.a0380d29.js
  61. 0 0
      virgo.wzfrontend/src/main/resources/static/console/static/js/494-legacy.56878bc6.js
  62. 0 0
      virgo.wzfrontend/src/main/resources/static/console/static/js/494.0d892db7.js
  63. 1 1
      virgo.wzfrontend/src/main/resources/static/console/static/js/500.ae098b9d.js
  64. 0 1
      virgo.wzfrontend/src/main/resources/static/console/static/js/5064.10cb745f.js
  65. 1 0
      virgo.wzfrontend/src/main/resources/static/console/static/js/5064.ba118eda.js
  66. 0 0
      virgo.wzfrontend/src/main/resources/static/console/static/js/5427.c48cb0d1.js
  67. 1 1
      virgo.wzfrontend/src/main/resources/static/console/static/js/5539.e85fc4e5.js
  68. 0 0
      virgo.wzfrontend/src/main/resources/static/console/static/js/5721.8ee95c98.js
  69. 1 1
      virgo.wzfrontend/src/main/resources/static/console/static/js/5778-legacy.b2d37a05.js
  70. 1 1
      virgo.wzfrontend/src/main/resources/static/console/static/js/5819.def2a3ed.js
  71. 0 1
      virgo.wzfrontend/src/main/resources/static/console/static/js/6055-legacy.18a54515.js
  72. 1 0
      virgo.wzfrontend/src/main/resources/static/console/static/js/6055-legacy.1d2c25e0.js
  73. 1 0
      virgo.wzfrontend/src/main/resources/static/console/static/js/6235-legacy.7cda0d9b.js
  74. 0 1
      virgo.wzfrontend/src/main/resources/static/console/static/js/6235-legacy.d4809b9b.js
  75. 1 0
      virgo.wzfrontend/src/main/resources/static/console/static/js/6235.227a538a.js
  76. 0 1
      virgo.wzfrontend/src/main/resources/static/console/static/js/6235.605d79f9.js
  77. 1 1
      virgo.wzfrontend/src/main/resources/static/console/static/js/6252-legacy.6a744f5b.js
  78. 1 1
      virgo.wzfrontend/src/main/resources/static/console/static/js/6252.6c6b0c30.js
  79. 1 1
      virgo.wzfrontend/src/main/resources/static/console/static/js/6264-legacy.1f42bee1.js
  80. 1 1
      virgo.wzfrontend/src/main/resources/static/console/static/js/6448.02356e97.js
  81. 1 1
      virgo.wzfrontend/src/main/resources/static/console/static/js/6696-legacy.2e7ef363.js
  82. 1 1
      virgo.wzfrontend/src/main/resources/static/console/static/js/6696.e38a6c82.js
  83. 0 1
      virgo.wzfrontend/src/main/resources/static/console/static/js/7023.879c8c50.js
  84. 1 0
      virgo.wzfrontend/src/main/resources/static/console/static/js/7023.abfd9a62.js
  85. 1 1
      virgo.wzfrontend/src/main/resources/static/console/static/js/7072-legacy.73f348e8.js
  86. 1 0
      virgo.wzfrontend/src/main/resources/static/console/static/js/7383-legacy.24ec2525.js
  87. 0 1
      virgo.wzfrontend/src/main/resources/static/console/static/js/7383-legacy.4394795f.js
  88. 0 0
      virgo.wzfrontend/src/main/resources/static/console/static/js/7431-legacy.65f70611.js
  89. 0 0
      virgo.wzfrontend/src/main/resources/static/console/static/js/7431.f0813df4.js
  90. 0 1
      virgo.wzfrontend/src/main/resources/static/console/static/js/7584-legacy.4f98bac4.js
  91. 1 0
      virgo.wzfrontend/src/main/resources/static/console/static/js/7584-legacy.b14f8558.js
  92. 0 1
      virgo.wzfrontend/src/main/resources/static/console/static/js/7584.6e4992e5.js
  93. 1 0
      virgo.wzfrontend/src/main/resources/static/console/static/js/7584.9c2de0b9.js
  94. 1 1
      virgo.wzfrontend/src/main/resources/static/console/static/js/7694.1c760abe.js
  95. 1 1
      virgo.wzfrontend/src/main/resources/static/console/static/js/7815-legacy.5ca5130f.js
  96. 1 1
      virgo.wzfrontend/src/main/resources/static/console/static/js/7815.872a8c8b.js
  97. 0 1
      virgo.wzfrontend/src/main/resources/static/console/static/js/8126-legacy.36f473ba.js
  98. 1 0
      virgo.wzfrontend/src/main/resources/static/console/static/js/8126-legacy.cbd0503d.js
  99. 0 0
      virgo.wzfrontend/src/main/resources/static/console/static/js/8195-legacy.e3b9e923.js
  100. 0 0
      virgo.wzfrontend/src/main/resources/static/console/static/js/843-legacy.a3136f8e.js

+ 359 - 361
virgo.wzfrontend/console/src/components/common/upload.vue

@@ -1,362 +1,360 @@
-<template>
-	<div class="common-update">
-		<div v-if="type === 'preview'">
-			<div class="no-tips" v-if="fileList.length === 0">暂无附件</div>
-			<div class="common-perview-image" v-else>
-				<div class="common-update-image-box" v-for="(item,index) in fileList" :key="item.id">
-					<div class="el-image video-image" v-if="item.type === 'mp4'">
-						<div class="video-icon">
-							<i class="el-icon-video-play" @click="openVideo(item)"></i>
-						</div>
-						<img :src="videoPreviewList[item.id]" class="el-image__inner">
-					</div>
-					<el-image :src="item.url" :preview-src-list="[item.url]" v-else>
-						<div slot="error" class="image-slot">
-							<el-tooltip class="item" effect="dark" :content="item.name" placement="bottom">
-								<div class="image-text">
-									<span>{{item.type.toUpperCase()}}</span>
-									<div class="file-download">
-										<i class="el-icon-download" @click="download(item)"></i>
-									</div>
-								</div>
-							</el-tooltip>
-						</div>
-					</el-image>
-				</div>
-			</div>
-		</div>
-		<div v-else>
-			<div class="common-update-image">
-				<div class="common-update-image-box" v-for="(item,index) in fileList" :key="item.id">
-					<div class="el-image video-image" v-if="item.type === 'mp4'">
-						<div class="video-icon">
-							<i class="el-icon-video-play" @click="openVideo(item)"></i>
-						</div>
-						<img :src="videoPreviewList[item.id]" class="el-image__inner">
-					</div>
-					<el-image :src="item.url" :preview-src-list="[item.url]" v-else>
-						<div slot="error" class="image-slot">
-							<el-tooltip class="item" effect="dark" :content="item.name" placement="bottom">
-								<div class="image-text">{{item.type.toUpperCase()}}</div>
-							</el-tooltip>
-						</div>
-					</el-image>
-					<div class="common-update-close" @click="removeFile(index)">
-						<i class="el-icon-close"></i>
-					</div>
-				</div>
-				<el-upload :action="action" :headers="headers" :show-file-list="false" name="uploadFile"
-					:before-upload="beforeUpload" :on-success="successFile" :on-error="errorFile" :accept="accept"
-					v-if="fileList.length < maxLen" :on-progress="progress" :limit="maxLen" :on-exceed="handleExceed"
-					:multiple="maxLen === 1 ? false : true">
-					<div class="common-update-button">
-						<i class="iconfont huifont-xinzeng"></i>
-						<div class="common-update-button-label">{{text}}</div>
-					</div>
-				</el-upload>
-			</div>
-			<div class="update-image-tips"><span class="color-red">*</span> 请上传小于10M的文件</div>
-		</div>
-		<el-dialog :close-on-click-modal="false" :title="video.name" custom-class="monitor-dialog" :visible.sync="visible" width="900px"
-			height="500px" :append-to-body="true">
-			<div class="video-box">
-				<video v-if="visible" width="900" height="445" controls>
-					<source :src="video.url" type="video/mp4" />
-				</video>
-			</div>
-		</el-dialog>
-	</div>
-</template>
-
-<script>
-	import config from '@/config';
-	import {
-		getToken
-	} from '@/uitls/auth';
-	export default {
-		props: {
-			list: {
-				type: Array,
-				default: () => {
-					return []
-				}
-			},
-			type: {
-				type: String,
-				default: 'preview'
-			},
-			maxLen: {
-				type: Number,
-				default: 5
-			},
-			text: {
-				type: String,
-				default: '上传图片'
-			},
-			accept: {
-				type: String,
-				default: '.png, .jpg, .jpeg'
-			},
-		},
-		data() {
-			return {
-				action: config.baseURL + '/file/filenode/-1', //上传地址
-				headers: {
-					token: ''
-				},
-				url: '',
-				srcList: [],
-				fileList: [],
-				videoPreviewList: {},
-				visible: false,
-				video: {}
-			};
-		},
-		created() {
-			this.headers.token = getToken();
-			this.fileList = JSON.parse(JSON.stringify(this.list));
-		},
-		methods: {
-			beforeUpload(file) {
-				//上传前
-				if ((parseInt(file.size) / 1024 / 1024) > 10) {
-					//判断上传的文件不大于30M
-					this.$message.warning('请上传小于10M的文件');
-					return false;
-				}
-			},
-			progress(e) {
-				let percent = e.percent >= 100 ? 99 : parseInt(e.percent)
-				this.$loading({
-					percent: (percent + '%')
-				});
-			},
-			successFile(response, file, fileList) {
-				//上传成功
-				if (!response.data) return this.errorFile();
-				this.$message.success('上传成功');
-				let data = response.data;
-				let typeList = data.name.split('.');
-				this.fileList.push({
-					id: data.id,
-					name: data.name,
-					url: data.node.url,
-					type: typeList[typeList.length - 1]
-				});
-				this.$loading.close();
-			},
-			errorFile() {
-				//上传失败
-				this.$message.error('上传失败');
-				this.$loading.close();
-			},
-			removeFile(index) {
-				this.$confirm('确定要删除该文件?', () => {
-					this.fileList.splice(index, 1);
-				});
-			},
-			download(item) {
-				window.location.href = config.baseURL + '/file/filenode/' + item.id;
-			},
-			openVideo(item) {
-				this.video = item;
-				this.visible = true;
-			},
-			handleExceed(files, fileList) {
-				console.log(files);
-				console.log(fileList);
-				this.$message.warning('最多上传' + this.maxLen + '个文件,当前已上传' + fileList.length + '个文件,请重新选择');
-			},
-			mp4Preview(item) {
-				const video = document.createElement('video') // 也可以自己创建video
-				video.src = item.url // url地址 url跟 视频流是一样的
-				video.crossOrigin = '*' // 解决跨域问题,也就是提示污染资源无法转换视频
-				video.currentTime = 1 // 第一帧
-				video.oncanplay = () => {
-					let canvas = document.createElement('canvas') // 获取 canvas 对象
-					const ctx = canvas.getContext('2d') // 绘制2d
-					canvas.width = video.clientWidth ? video.clientWidth : 320 // 获取视频宽度
-					canvas.height = video.clientHeight ? video.clientHeight : 320 //获取视频高度
-					// 利用canvas对象方法绘图
-					ctx.drawImage(video, 0, 0, canvas.width, canvas.height)
-					// 转换成base64形式
-					const videoFirstImgsrc = canvas.toDataURL('image/png') // 截取后的视频封面
-					this.videoPreviewList[item.id] = videoFirstImgsrc;
-					this.$forceUpdate();
-					video.remove()
-					canvas.remove();
-				}
-			}
-		},
-		watch: {
-			list(val) {
-				this.fileList = JSON.parse(JSON.stringify(val));
-			},
-			fileList() {
-				for (let i = 0; i < this.fileList.length; i++) {
-					if (this.fileList[i].type === 'mp4') {
-						this.mp4Preview(this.fileList[i])
-					}
-				}
-			}
-		},
-	}
-</script>
-
-<style lang="scss">
-	.el-dialog.monitor-dialog {
-		height: 500px;
-		margin-top: 20vh !important;
-	}
-
-	.common-update {
-		display: flex;
-		flex-wrap: wrap;
-
-		.update-image-tips {
-			font-size: 12px;
-			opacity: 0.7;
-		}
-
-		.video-image {
-			cursor: pointer;
-			position: relative;
-
-			&:hover {
-				.video-icon {
-					opacity: 1;
-				}
-			}
-
-			.video-icon {
-				position: absolute;
-				top: 0;
-				left: 0;
-				right: 0;
-				bottom: 0;
-				display: flex;
-				align-items: center;
-				justify-content: center;
-				background: rgba(0, 0, 0, 0.6);
-				opacity: 0;
-				transition: opacity 200ms;
-
-				i {
-					font-size: 24px;
-				}
-			}
-		}
-
-		.common-update-button {
-			width: 100px;
-			height: 100px;
-			border: 1px dashed $--input-border;
-			display: flex;
-			color: $--color-common;
-			flex-direction: column;
-			justify-content: center;
-			margin: 4px 0;
-
-			.huifont-xinzeng {
-				line-height: 20px;
-				font-size: 20px;
-			}
-
-			.common-update-button-label {
-				font-size: 14px;
-				line-height: 20px;
-				padding-top: 10px;
-			}
-		}
-
-		.common-perview-image {
-			display: flex;
-			flex-wrap: wrap;
-
-			.el-image {
-				width: 64px;
-				height: 64px;
-				border-radius: 2px;
-				background: transparent;
-			}
-		}
-
-		.image-slot {
-			width: 100%;
-			height: 100%;
-			border-radius: 4px;
-			background: #253642;
-			position: relative;
-
-			.file-download {
-				position: absolute;
-				display: none;
-				align-items: center;
-				justify-content: center;
-				font-size: 20px;
-				background: rgba(0, 0, 0, 0.8);
-				top: 0;
-				left: 0;
-				right: 0;
-				bottom: 0;
-				color: #fff;
-				cursor: pointer;
-			}
-
-			.image-text {
-				font-size: 20px;
-				width: 100%;
-				height: 100%;
-				display: flex;
-				align-items: center;
-				justify-content: center;
-				color: #fff;
-				font-weight: bold;
-
-				&:hover {
-					.file-download {
-						display: flex;
-					}
-				}
-			}
-
-		}
-
-		.common-update-image-box {
-			display: flex;
-			position: relative;
-			margin-right: 4px;
-		}
-
-		.common-update-image {
-			display: flex;
-			flex-wrap: wrap;
-
-			.common-update-image-box {
-				margin: 4px 8px 4px 0;
-			}
-
-			.el-image {
-				width: 100px;
-				height: 100px;
-				border-radius: 2px;
-				background: transparent;
-			}
-
-			.common-update-close {
-				position: absolute;
-				right: -7px;
-				top: -7px;
-				background: #394358;
-				color: $--color-common;
-				width: 14px;
-				height: 14px;
-				line-height: 14px;
-				text-align: center;
-				border-radius: 50%;
-				font-size: 10px;
-				cursor: pointer;
-			}
-		}
-	}
+<template>
+	<div class="common-update">
+		<div v-if="type === 'preview'">
+			<div class="no-tips" v-if="fileList.length === 0">暂无附件</div>
+			<div class="common-perview-image" v-else>
+				<div class="common-update-image-box" v-for="(item,index) in fileList" :key="item.id">
+					<div class="el-image video-image" v-if="item.type === 'mp4'">
+						<div class="video-icon">
+							<i class="el-icon-video-play" @click="openVideo(item)"></i>
+						</div>
+						<img :src="videoPreviewList[item.id]" class="el-image__inner">
+					</div>
+					<el-image :src="item.url" :preview-src-list="[item.url]" v-else>
+						<div slot="error" class="image-slot">
+							<el-tooltip class="item" effect="dark" :content="item.name" placement="bottom">
+								<div class="image-text">
+									<span>{{item.type.toUpperCase()}}</span>
+									<div class="file-download">
+										<i class="el-icon-download" @click="download(item)"></i>
+									</div>
+								</div>
+							</el-tooltip>
+						</div>
+					</el-image>
+				</div>
+			</div>
+		</div>
+		<div v-else>
+			<div class="common-update-image">
+				<div class="common-update-image-box" v-for="(item,index) in fileList" :key="item.id">
+					<div class="el-image video-image" v-if="item.type === 'mp4'">
+						<div class="video-icon">
+							<i class="el-icon-video-play" @click="openVideo(item)"></i>
+						</div>
+						<img :src="videoPreviewList[item.id]" class="el-image__inner">
+					</div>
+					<el-image :src="item.url" :preview-src-list="[item.url]" v-else>
+						<div slot="error" class="image-slot">
+							<el-tooltip class="item" effect="dark" :content="item.name" placement="bottom">
+								<div class="image-text">{{item.type.toUpperCase()}}</div>
+							</el-tooltip>
+						</div>
+					</el-image>
+					<div class="common-update-close" @click="removeFile(index)">
+						<i class="el-icon-close"></i>
+					</div>
+				</div>
+				<el-upload :action="action" :headers="headers" :show-file-list="false" name="uploadFile"
+					:before-upload="beforeUpload" :on-success="successFile" :on-error="errorFile" :accept="accept"
+					v-if="fileList.length < maxLen" :on-progress="progress" :limit="maxLen" :on-exceed="handleExceed"
+					:multiple="maxLen === 1 ? false : true">
+					<div class="common-update-button">
+						<i class="iconfont huifont-xinzeng"></i>
+						<div class="common-update-button-label">{{text}}</div>
+					</div>
+				</el-upload>
+			</div>
+			<div class="update-image-tips"><span class="color-red">*</span> 请上传小于10M的文件</div>
+		</div>
+		<el-dialog :close-on-click-modal="false" :title="video.name" custom-class="monitor-dialog"
+			:visible.sync="visible" width="900px" height="500px" :append-to-body="true">
+			<div class="video-box">
+				<video v-if="visible" width="900" height="445" controls>
+					<source :src="video.url" type="video/mp4" />
+				</video>
+			</div>
+		</el-dialog>
+	</div>
+</template>
+
+<script>
+	import config from '@/config';
+	import {
+		getToken
+	} from '@/uitls/auth';
+	export default {
+		props: {
+			list: {
+				type: Array,
+				default: () => {
+					return []
+				}
+			},
+			type: {
+				type: String,
+				default: 'preview'
+			},
+			maxLen: {
+				type: Number,
+				default: 5
+			},
+			text: {
+				type: String,
+				default: '上传图片'
+			},
+			accept: {
+				type: String,
+				default: '.png, .jpg, .jpeg'
+			},
+		},
+		data() {
+			return {
+				action: config.baseURL + '/file/filenode/-1', //上传地址
+				headers: {
+					token: ''
+				},
+				url: '',
+				srcList: [],
+				fileList: [],
+				videoPreviewList: {},
+				visible: false,
+				video: {}
+			};
+		},
+		created() {
+			this.headers.token = getToken();
+			this.fileList = JSON.parse(JSON.stringify(this.list));
+		},
+		methods: {
+			beforeUpload(file) {
+				//上传前
+				if ((parseInt(file.size) / 1024 / 1024) > 10) {
+					//判断上传的文件不大于30M
+					this.$message.warning('请上传小于10M的文件');
+					return false;
+				}
+			},
+			progress(e) {
+				let percent = e.percent >= 100 ? 99 : parseInt(e.percent)
+				this.$loading({
+					percent: (percent + '%')
+				});
+			},
+			successFile(response, file, fileList) {
+				//上传成功
+				if (!response.data) return this.errorFile();
+				this.$message.success('上传成功');
+				let data = response.data;
+				let typeList = data.name.split('.');
+				this.fileList.push({
+					id: data.id,
+					name: data.name,
+					url: data.node.url,
+					type: typeList[typeList.length - 1]
+				});
+				this.$loading.close();
+			},
+			errorFile() {
+				//上传失败
+				this.$message.error('上传失败');
+				this.$loading.close();
+			},
+			removeFile(index) {
+				this.$confirm('确定要删除该文件?', () => {
+					this.fileList.splice(index, 1);
+				});
+			},
+			download(item) {
+				window.location.href = config.baseURL + '/file/filenode/' + item.id;
+			},
+			openVideo(item) {
+				this.video = item;
+				this.visible = true;
+			},
+			handleExceed(files, fileList) {
+				this.$message.warning('最多上传' + this.maxLen + '个文件,当前已上传' + fileList.length + '个文件,请重新选择');
+			},
+			mp4Preview(item) {
+				const video = document.createElement('video') // 也可以自己创建video
+				video.src = item.url // url地址 url跟 视频流是一样的
+				video.crossOrigin = '*' // 解决跨域问题,也就是提示污染资源无法转换视频
+				video.currentTime = 1 // 第一帧
+				video.oncanplay = () => {
+					let canvas = document.createElement('canvas') // 获取 canvas 对象
+					const ctx = canvas.getContext('2d') // 绘制2d
+					canvas.width = video.clientWidth ? video.clientWidth : 320 // 获取视频宽度
+					canvas.height = video.clientHeight ? video.clientHeight : 320 //获取视频高度
+					// 利用canvas对象方法绘图
+					ctx.drawImage(video, 0, 0, canvas.width, canvas.height)
+					// 转换成base64形式
+					const videoFirstImgsrc = canvas.toDataURL('image/png') // 截取后的视频封面
+					this.videoPreviewList[item.id] = videoFirstImgsrc;
+					this.$forceUpdate();
+					video.remove()
+					canvas.remove();
+				}
+			}
+		},
+		watch: {
+			list(val) {
+				this.fileList = JSON.parse(JSON.stringify(val));
+			},
+			fileList() {
+				for (let i = 0; i < this.fileList.length; i++) {
+					if (this.fileList[i].type === 'mp4') {
+						this.mp4Preview(this.fileList[i])
+					}
+				}
+			}
+		},
+	}
+</script>
+
+<style lang="scss">
+	.el-dialog.monitor-dialog {
+		height: 500px;
+		margin-top: 20vh !important;
+	}
+
+	.common-update {
+		display: flex;
+		flex-wrap: wrap;
+
+		.update-image-tips {
+			font-size: 12px;
+			opacity: 0.7;
+		}
+
+		.video-image {
+			cursor: pointer;
+			position: relative;
+
+			&:hover {
+				.video-icon {
+					opacity: 1;
+				}
+			}
+
+			.video-icon {
+				position: absolute;
+				top: 0;
+				left: 0;
+				right: 0;
+				bottom: 0;
+				display: flex;
+				align-items: center;
+				justify-content: center;
+				background: rgba(0, 0, 0, 0.6);
+				opacity: 0;
+				transition: opacity 200ms;
+
+				i {
+					font-size: 24px;
+				}
+			}
+		}
+
+		.common-update-button {
+			width: 100px;
+			height: 100px;
+			border: 1px dashed $--input-border;
+			display: flex;
+			color: $--color-common;
+			flex-direction: column;
+			justify-content: center;
+			margin: 4px 0;
+
+			.huifont-xinzeng {
+				line-height: 20px;
+				font-size: 20px;
+			}
+
+			.common-update-button-label {
+				font-size: 14px;
+				line-height: 20px;
+				padding-top: 10px;
+			}
+		}
+
+		.common-perview-image {
+			display: flex;
+			flex-wrap: wrap;
+
+			.el-image {
+				width: 64px;
+				height: 64px;
+				border-radius: 2px;
+				background: transparent;
+			}
+		}
+
+		.image-slot {
+			width: 100%;
+			height: 100%;
+			border-radius: 4px;
+			background: #253642;
+			position: relative;
+
+			.file-download {
+				position: absolute;
+				display: none;
+				align-items: center;
+				justify-content: center;
+				font-size: 20px;
+				background: rgba(0, 0, 0, 0.8);
+				top: 0;
+				left: 0;
+				right: 0;
+				bottom: 0;
+				color: #fff;
+				cursor: pointer;
+			}
+
+			.image-text {
+				font-size: 20px;
+				width: 100%;
+				height: 100%;
+				display: flex;
+				align-items: center;
+				justify-content: center;
+				color: #fff;
+				font-weight: bold;
+
+				&:hover {
+					.file-download {
+						display: flex;
+					}
+				}
+			}
+
+		}
+
+		.common-update-image-box {
+			display: flex;
+			position: relative;
+			margin-right: 4px;
+		}
+
+		.common-update-image {
+			display: flex;
+			flex-wrap: wrap;
+
+			.common-update-image-box {
+				margin: 4px 8px 4px 0;
+			}
+
+			.el-image {
+				width: 100px;
+				height: 100px;
+				border-radius: 2px;
+				background: transparent;
+			}
+
+			.common-update-close {
+				position: absolute;
+				right: -7px;
+				top: -7px;
+				background: #394358;
+				color: $--color-common;
+				width: 14px;
+				height: 14px;
+				line-height: 14px;
+				text-align: center;
+				border-radius: 50%;
+				font-size: 10px;
+				cursor: pointer;
+			}
+		}
+	}
 </style>

+ 9 - 2
virgo.wzfrontend/console/src/components/common/uploadFile.vue

@@ -1,7 +1,8 @@
 <template>
 	<div class="document-upload">
-		<el-upload :action="action" name="uploadFile" ref="upload" :headers="headers" :on-success="successFile"
-			:before-upload="beforeUpload" :on-error="errorUpload" :show-file-list="false" :on-progress="progress">
+		<el-upload :action="action" name="uploadFile" ref="upload" :accept="accept" :headers="headers"
+			:on-success="successFile" :before-upload="beforeUpload" :on-error="errorUpload" :show-file-list="false"
+			:on-progress="progress">
 			<div class="bim-update-button">
 				<i class="el-icon-plus"></i>
 			</div>
@@ -15,6 +16,12 @@
 		getToken
 	} from '@/uitls/auth';
 	export default {
+		props: {
+			accept: {
+				type: String,
+				default: '*'
+			}
+		},
 		data() {
 			return {
 				action: config.baseURL + '/file/filenode/-1',

+ 9 - 4
virgo.wzfrontend/console/src/components/system/level/deviceLevel.vue

@@ -9,7 +9,7 @@
 					<span class="tree-node-label">{{ data.name }}-{{ data.sign }}</span>
 					<div class="tree-node-operation">
 						<i class="iconfont huifont-moxingguanli" v-if="data.children.length === 0"
-							@click.stop="modelVisible = true">
+							@click.stop="model(data.id)">
 						</i>
 						<i class="iconfont huifont-xinzeng" @click.stop="insert(data.id)"></i>
 						<i class="iconfont huifont-bianji" @click.stop="update(data)"></i>
@@ -40,9 +40,9 @@
 					</div>
 				</div>
 			</el-dialog>
-			<el-dialog :close-on-click-modal="false" title="模型列表" :visible.sync="modelVisible" width="900px"
+			<el-dialog :close-on-click-modal="false" title="模型列表" :visible.sync="modelVisible" width="1100px"
 				:append-to-body="true">
-				<model-down v-if="modelVisible"></model-down>
+				<model-down v-if="modelVisible" :modelLevelId="modelLevelId"></model-down>
 			</el-dialog>
 		</div>
 	</div>
@@ -72,7 +72,8 @@
 					remark: '',
 					isp: 1
 				},
-				modelVisible: false
+				modelVisible: false,
+				modelLevelId: ''
 			}
 		},
 		created() {
@@ -99,6 +100,10 @@
 				}
 				this.dialogVisible = true;
 			},
+			model(id) {
+				this.modelLevelId = id;
+				this.modelVisible = true;
+			},
 			update(data) {
 				this.form = JSON.parse(JSON.stringify(data));
 				this.dialogVisible = true;

+ 77 - 33
virgo.wzfrontend/console/src/components/work/common/modelDown.vue

@@ -1,56 +1,100 @@
 <template>
-	<div class="hui-flex hui-dialog">
-		<div class="hui-flex-box hui-dialog-content">
-			<el-form ref="form" label-position="top" :model="form">
-				<el-form-item label="模型名称" prop="name" :rules="[{required: true, message: '请输入项目名称'}]">
-					<el-input type="text" v-model="form.name" placeholder="请输入项目名称"></el-input>
-				</el-form-item>
-				<el-form-item label="模型类型" prop="type" :rules="[{required: true, message: '请选模型类型'}]">
-					<el-select v-model="form.type" placeholder="请选择项目类型">
-						<el-option :label="item.name" :value="item.id" v-for="(item,index) in $field.field.modelType"
-							:key="item.id">
-						</el-option>
-					</el-select>
-				</el-form-item>
-				<el-form-item label="3D模型" class="hui-textarea">
-					<div style="height: 400px;width: 100%;">
-						<three-model></three-model>
-					</div>
-				</el-form-item>
-			</el-form>
+	<div class="hui-flex hui-dialog model-3d-list">
+		<div class="hui-content-insert">
+			<el-button type="primary" size="medium" @click="insertModel">上传模型</el-button>
 		</div>
-		<div class="hui-dialog-submit">
-			<el-button size="medium" @click="$emit('callback')">取 消</el-button>
-			<el-button size="medium" type="primary" @click="submit" :loading="loading">保 存</el-button>
+		<div class="hui-flex-box">
+			<div class="list">
+				<div class="model-3d-item" v-for="(item,index) in list" :key="item.id">
+					<div class="model-3d-image">
+						<img :src="item.previewURL" alt="aa.png" />
+					</div>
+					<div class="name">{{item.name}} </div>
+				</div>
+			</div>
 		</div>
+		<el-dialog :close-on-click-modal="false" :title="isUpdate?'编辑':'新增'" :visible.sync="visible" width="900px"
+			:append-to-body="true">
+			<model-form v-if="visible" @callback="callback" :isUpdate="isUpdate" :detailId="detailId" :levelId="levelId"
+				:modelLevelId="modelLevelId">
+			</model-form>
+		</el-dialog>
 	</div>
 </template>
 
 <script>
-	import threeModel from '@/components/work/common/threeModel'
+	import modelForm from '@/components/work/common/modelForm'
+	import {
+		get3DModel
+	} from '@/httpApi/property'
 	export default {
+		props: ['levelId', 'modelLevelId'],
 		data() {
 			return {
-				form: {
-					name: '',
-					type: 1
-				},
-				loading: false
+				list: [],
+				isUpdate: false,
+				visible: false,
+				detailId: '',
+				option: {}
 			}
 		},
 		created() {
-
+			if (this.modelLevelId) this.option['modelLevelId'] = this.modelLevelId;
+			if (this.levelId) this.option['levelId'] = this.levelId;
+			this.init();
 		},
 		components: {
-			threeModel
+			modelForm
 		},
 		methods: {
-			submit() {
-
+			init() {
+				get3DModel(this.option).then(res => {
+					if (res.state) {
+						this.list = res.data;
+					}
+				})
+			},
+			insertModel() {
+				this.isUpdate = false;
+				this.visible = true;
+			},
+			callback(type) {
+				if (type === 'init') this.init();
+				this.visible = false;
 			}
 		}
 	}
 </script>
 
-<style>
+<style lang="scss">
+	.model-3d-list {
+		padding: 20px;
+
+		.list {
+			display: flex;
+			flex-wrap: wrap;
+			padding: 20px 0;
+		}
+
+		.model-3d-item {
+			width: 25%;
+			border: 1px solid $--color-border;
+			border-radius: 4px;
+			overflow: hidden;
+			cursor: pointer;
+
+			.model-3d-image {
+				height: 160px;
+			}
+
+			img {
+				width: 100%;
+				height: 100%;
+			}
+
+			.name {
+				padding: 10px;
+			}
+		}
+	}
 </style>

+ 145 - 0
virgo.wzfrontend/console/src/components/work/common/modelForm.vue

@@ -0,0 +1,145 @@
+<template>
+	<div class="hui-flex hui-dialog">
+		<div class="hui-flex-box hui-dialog-content">
+			<el-form ref="form" label-position="top" :model="form">
+				<el-form-item label="模型名称" prop="name" :rules="[{required: true, message: '请输入项目名称'}]">
+					<el-input type="text" v-model="form.name" placeholder="请输入项目名称"></el-input>
+				</el-form-item>
+				<el-form-item label="模型类型" prop="type" :rules="[{required: true, message: '请选模型类型'}]">
+					<el-select v-model="form.type" placeholder="请选择项目类型" @change="changeModel">
+						<el-option :label="item.name" :value="item.id" v-for="(item,index) in $field.field.modelType"
+							:key="item.id">
+						</el-option>
+					</el-select>
+				</el-form-item>
+				<el-form-item label="3D模型">
+					<div class="model-3d-box">
+						<div class="upload-model" v-if="!form.address" @click="uploadModel">
+							<i class="el-icon-upload"></i>
+							<span>点击上传模型</span>
+						</div>
+						<three-model ref="threeModel" v-else :url="form.address" :type="form.type">
+						</three-model>
+					</div>
+					<upload-file ref="upload" v-show="false" @changeFile="changeFile" :accept="accept"></upload-file>
+				</el-form-item>
+				<el-form-item v-if="form.address">
+					<template slot="label">
+						<div>
+							<span style="margin-right: 10px;">模型预览图</span>
+							<el-button size="mini" type="primary" @click="getSnapshot">获取快照</el-button>
+						</div>
+					</template>
+					<div class="model-3d-box">
+						<img :src="form.previewURL" v-if="form.previewURL" alt="" style="width: 100%;height: 100%;" />
+					</div>
+				</el-form-item>
+			</el-form>
+		</div>
+		<div class="hui-dialog-submit">
+			<el-button size="medium" @click="$emit('callback')">取 消</el-button>
+			<el-button size="medium" type="primary" @click="submit" :loading="loading">保 存</el-button>
+		</div>
+	</div>
+</template>
+
+<script>
+	import threeModel from '@/components/work/common/threeModel'
+	import uploadFile from '@/components/common/uploadFile'
+	import {
+		insert3DModel
+	} from '@/httpApi/property'
+	import {
+		uploadBase64
+	} from '@/httpApi/datacenter.js'
+	export default {
+		props: ['levelId', 'modelLevelId'],
+		data() {
+			return {
+				form: {
+					name: '',
+					type: 1,
+					address: '',
+					previewURL: ''
+				},
+				loading: false,
+				url: '',
+				accept: '.fbx, .FBX',
+				snapshotUrl: ''
+			}
+		},
+		created() {
+			this.form['userId'] = this.$store.getters.user.userId;
+			if (this.levelId) this.form['levelId'] = this.levelId;
+			if (this.modelLevelId) this.form['modelLevelId'] = this.modelLevelId;
+		},
+		components: {
+			uploadFile,
+			threeModel
+		},
+		methods: {
+			changeModel(val) {
+				let arr = this.$field.findTypeNameByList('modelType', String(val));
+				if (arr.length === 0) return;
+				this.accept = arr[0].accept || '.fbx, .FBX';
+			},
+			uploadModel() {
+				this.$refs.upload.reloadUpload();
+			},
+			submit() {
+				this.loading = true;
+				this.$refs.form.validate((valid) => {
+					if (valid) {
+						insert3DModel(this.form).then(this.successFunc)
+					} else {
+						this.loading = false;
+						return false;
+					}
+				});
+			},
+			successFunc(res) {
+				this.loading = false;
+				if (res.state) {
+					this.$message.success('操作成功');
+					this.$emit('callback', 'init');
+				}
+			},
+			changeFile(data) {
+				this.form.address = data.url;
+			},
+			getSnapshot() {
+				let url = this.$refs.threeModel.getSnapshot();
+				uploadBase64({
+					"base64": url
+				}).then(res => {
+					if (res.state) {
+						this.form.previewURL = res.data.node.url;
+					}
+				})
+			}
+		}
+	}
+</script>
+
+<style lang="scss">
+	.model-3d-box {
+		height: 260px;
+		width: 100%;
+
+		.upload-model {
+			width: 100%;
+			height: 100%;
+			border-radius: 6px;
+			border: 1px solid $--color-border;
+			display: flex;
+			align-items: center;
+			justify-content: center;
+			flex-direction: column;
+			cursor: pointer;
+
+			.el-icon-upload {
+				font-size: 40px;
+			}
+		}
+	}
+</style>

+ 32 - 15
virgo.wzfrontend/console/src/components/work/common/threeModel.vue

@@ -7,22 +7,39 @@
 <script>
 	import threeControls from '@/uitls/threeControls';
 	export default {
-		name: 'app',
+		props: ['url', 'type'],
+		data() {
+			return {
+				threeObj: null,
+				imgUrl: ''
+			}
+		},
 		created() {
-			this.$nextTick(() => {
-				let threeObj = new threeControls({
-					container: document.getElementById('threeModel')
-				});
-				// threeObj.setAxisHelper();
-				threeObj.loaderGLTF('https://file-node.oss-cn-shanghai.aliyuncs.com/youji/ec455ebd72664531acfcb81657d44266');
-				// threeObj.setState();
-				threeObj.OrbitControls();
-				// threeObj.inserClickFunc();
-				// threeObj.initPointerLockControls();
-				// threeObj.FlyControls();
-				threeObj.render();
-			})
-		}
+			if (this.url) this.init();
+		},
+		methods: {
+			init() {
+				this.$nextTick(() => {
+					this.threeObj = new threeControls({
+						container: document.getElementById('threeModel')
+					});
+					// threeObj.setAxisHelper();
+					if (this.type == 1) {
+						this.threeObj.loaderFBX(this.url);
+					} else if (this.type == 2) {
+
+					} else if (this.type == 3 || this.type == 4) {
+						this.threeObj.loaderGLTF(this.url);
+					}
+					// threeObj.setState();
+					this.threeObj.OrbitControls();
+					this.threeObj.render();
+				})
+			},
+			getSnapshot() {
+				return this.threeObj.getSnapshot();
+			}
+		},
 	}
 </script>
 

+ 12 - 5
virgo.wzfrontend/console/src/config/field.js

@@ -246,14 +246,21 @@ const supportingFacilities = [{
 }];
 const modelType = [{
 	id: 1,
-	name: 'FBX'
+	name: 'FBX',
+	accept: '.fbx, .FBX'
 }, {
 	id: 2,
-	name: 'OBJ'
+	name: 'OBJ',
+	accept: '.obj, .OBJ'
 }, {
 	id: 3,
-	name: 'GLB'
-}]
+	name: 'GLB',
+	accept: '.glb, .GLB'
+}, {
+	id: 4,
+	name: 'GLTF',
+	accept: '.gltf, .GLTF'
+}]
 
 const findItem = (type, id) => {
 	return eval(type).find(node => node.id == id) || {
@@ -283,7 +290,7 @@ export default {
 		invoiceType,
 		serviceWorkWay,
 		clearWorkWay,
-		supportingFacilities,
+		supportingFacilities,
 		modelType
 	},
 	findTypeName(type, id) {

+ 11 - 0
virgo.wzfrontend/console/src/httpApi/datacenter.js

@@ -1,4 +1,15 @@
 import request from '@/axios'
+/* 
+ * 上传base64文件
+ * 
+ */
+export function uploadBase64(data) {
+	return request({
+		url: `/file/filenode/base64`,
+		method: 'post',
+		data: data
+	});
+}
 /* 
  * 获取目录列表
  * 

+ 58 - 0
virgo.wzfrontend/console/src/httpApi/property.js

@@ -265,4 +265,62 @@ export function getGoDownDetail(id) {
 		url: `/api/godown/${id}`,
 		method: 'get'
 	})
+}
+/* 
+ * 3D模型库列表
+ * 
+ * 
+ */
+export function get3DModel(data) {
+	return request({
+		url: `/api/operateDeviceModel/query`,
+		method: 'post',
+		data: data
+	})
+}
+/* 
+ * 新增3D模型库
+ * 
+ * 
+ */
+export function insert3DModel(data) {
+	return request({
+		url: `/api/operateDeviceModel`,
+		method: 'post',
+		data: data
+	})
+}
+/* 
+ * 编辑3D模型库
+ * 
+ * 
+ */
+export function update3DModel(data) {
+	return request({
+		url: `/api/operateDeviceModel`,
+		method: 'put',
+		data: data
+	})
+}
+/* 
+ * 删除3D模型库
+ * 
+ * 
+ */
+export function delete3DModel(id) {
+	return request({
+		url: `/api/operateDeviceModel/${id}`,
+		method: 'delete',
+	})
+}
+/* 
+ * 3D模型库详情
+ * 
+ * 
+ */
+export function get3DModelDetail(id) {
+	return request({
+		url: `/api/operateDeviceModel/${id}`,
+		method: 'get'
+	})
 }

+ 30 - 9
virgo.wzfrontend/console/src/uitls/threeControls.js

@@ -67,7 +67,7 @@ class threeControls {
 	initSence() { //初始化场景
 		scene = new THREE.Scene();
 		//场景背景颜色
-		scene.background = new THREE.Color('rgb(79, 98, 138)');
+		scene.background = new THREE.Color('rgb(20, 26, 36)');
 	}
 	setHemisphereLight() { //设置半球光;
 		/*
@@ -117,21 +117,28 @@ class threeControls {
 		let axesHelper = new THREE.AxesHelper(200);
 		scene.add(axesHelper);
 	}
-	loaderFBX() { //加载fbx模型
+	loaderFBX(url) { //加载fbx模型
 		const loader = new FBXLoader();
-		loader.load('./model/test.fbx', (object) => {
-			object.scale.multiplyScalar(0.9);
-			object.position.y = 0;
-			object.position.x = 0;
+		loader.load(url, (object) => {
+			console.log('FBX加载成功');
+			let box = new THREE.Box3().setFromObject(object);
+			let mdlen = box.max.x - box.min.x; //模型长度
+			let mdwid = box.max.z - box.min.z; //模型宽度
+			let mdhei = box.max.y - box.min.y; //模型高度
+			let x1 = box.min.x + mdlen / 2
+			let y1 = box.min.y + mdhei / 2
+			let z1 = box.min.z + mdwid / 2
+			object.position.set(-x1, -y1, -z1);
+			camera.position.set((mdlen / 2) + 20, (mdlen / 2) + 20, (mdlen / 2) + 20);
 			scene.add(object);
-			this.renderer.render(scene, camera);
+			renderer.render(scene, camera);
 		});
 	}
 	loaderGLTF(url) { //加载GLTF模型
 		const loader = new GLTFLoader();
 		let _self = this;
 		loader.load(url, gltf => {
-			console.log('加载成功');
+			console.log('GLTF加载成功');
 			gltf.scene.scale.set(1, 1, 1)
 			let group = gltf.scene;
 			let box = new THREE.Box3().setFromObject(group);
@@ -142,7 +149,16 @@ class threeControls {
 			let y1 = box.min.y + mdhei / 2
 			let z1 = box.min.z + mdwid / 2
 			group.position.set(-x1, -y1, -z1);
-			camera.position.set((mdlen / 2) + 10, (mdlen / 2) + 10, (mdlen / 2) + 100);
+			camera.position.set((mdlen / 2) + 10, (mdlen / 2) + 10, (mdlen / 2) + 10);
+			const center = box.getCenter(new THREE.Vector3());
+			const size = box.getSize(new THREE.Vector3());
+			// 计算相机的距离,使得模型正好填充整个视图
+			const maxSize = Math.max(size.x, size.y, size.z);
+			const cameraDistance = maxSize * 10;
+			// 更新相机FOV(如果需要)
+			const fov = (camera.far - camera.near) / 2;
+			camera.fov = THREE.MathUtils.radToDeg(2 * Math.atan(size.y / 2 / cameraDistance));
+			camera.updateProjectionMatrix();
 			scene.add(group);
 		});
 	}
@@ -314,6 +330,11 @@ class threeControls {
 		document.addEventListener('keydown', onKeyDown);
 		document.addEventListener('keyup', onKeyUp);
 	}
+	getSnapshot() {
+		renderer.clear();
+		renderer.render(scene, camera);
+		return renderer.domElement.toDataURL();
+	}
 	render() { //渲染
 		animate()
 	}

File diff suppressed because it is too large
+ 1 - 1
virgo.wzfrontend/src/main/resources/static/console/index.html


virgo.wzfrontend/src/main/resources/static/console/static/css/1888.9cfed5af.css → virgo.wzfrontend/src/main/resources/static/console/static/css/1888.232edf06.css


File diff suppressed because it is too large
+ 0 - 1
virgo.wzfrontend/src/main/resources/static/console/static/css/3065.e719da7b.css


File diff suppressed because it is too large
+ 1 - 0
virgo.wzfrontend/src/main/resources/static/console/static/css/3235.5594966c.css


File diff suppressed because it is too large
+ 1 - 0
virgo.wzfrontend/src/main/resources/static/console/static/css/3348.5594966c.css


File diff suppressed because it is too large
+ 0 - 1
virgo.wzfrontend/src/main/resources/static/console/static/css/843.e719da7b.css


virgo.wzfrontend/src/main/resources/static/console/static/css/8663.9cfed5af.css → virgo.wzfrontend/src/main/resources/static/console/static/css/8663.232edf06.css


File diff suppressed because it is too large
+ 1 - 0
virgo.wzfrontend/src/main/resources/static/console/static/css/8942.fd889f81.css


File diff suppressed because it is too large
+ 0 - 1
virgo.wzfrontend/src/main/resources/static/console/static/js/103.174197f0.js


File diff suppressed because it is too large
+ 1 - 0
virgo.wzfrontend/src/main/resources/static/console/static/js/103.511e1ba1.js


File diff suppressed because it is too large
+ 1 - 1
virgo.wzfrontend/src/main/resources/static/console/static/js/109-legacy.229109ed.js


File diff suppressed because it is too large
+ 1 - 1
virgo.wzfrontend/src/main/resources/static/console/static/js/1263-legacy.5fa68517.js


File diff suppressed because it is too large
+ 1 - 1
virgo.wzfrontend/src/main/resources/static/console/static/js/1263.9d9fb9c6.js


virgo.wzfrontend/src/main/resources/static/console/static/js/1361.d9208ab7.js → virgo.wzfrontend/src/main/resources/static/console/static/js/1361.b40c506b.js


File diff suppressed because it is too large
+ 1 - 1
virgo.wzfrontend/src/main/resources/static/console/static/js/1471-legacy.cf7f3478.js


File diff suppressed because it is too large
+ 1 - 1
virgo.wzfrontend/src/main/resources/static/console/static/js/1471.c3d7d6fa.js


virgo.wzfrontend/src/main/resources/static/console/static/js/1703-legacy.5fabf8c4.js → virgo.wzfrontend/src/main/resources/static/console/static/js/1703-legacy.feeb8a75.js


virgo.wzfrontend/src/main/resources/static/console/static/js/1703.c12235a3.js → virgo.wzfrontend/src/main/resources/static/console/static/js/1703.6e8204ea.js


File diff suppressed because it is too large
+ 1 - 1
virgo.wzfrontend/src/main/resources/static/console/static/js/1821-legacy.491f3664.js


File diff suppressed because it is too large
+ 1 - 0
virgo.wzfrontend/src/main/resources/static/console/static/js/1888.8f2fc782.js


File diff suppressed because it is too large
+ 0 - 1
virgo.wzfrontend/src/main/resources/static/console/static/js/1888.a4c7c371.js


File diff suppressed because it is too large
+ 1 - 1
virgo.wzfrontend/src/main/resources/static/console/static/js/191.0fb32dfc.js


File diff suppressed because it is too large
+ 1 - 1
virgo.wzfrontend/src/main/resources/static/console/static/js/2059.03f15905.js


File diff suppressed because it is too large
+ 1 - 1
virgo.wzfrontend/src/main/resources/static/console/static/js/2439-legacy.432b096d.js


File diff suppressed because it is too large
+ 1 - 1
virgo.wzfrontend/src/main/resources/static/console/static/js/2587-legacy.eda5ba99.js


File diff suppressed because it is too large
+ 1 - 1
virgo.wzfrontend/src/main/resources/static/console/static/js/2587.dc5b3ac4.js


File diff suppressed because it is too large
+ 1 - 0
virgo.wzfrontend/src/main/resources/static/console/static/js/2610.2300ce1f.js


File diff suppressed because it is too large
+ 0 - 1
virgo.wzfrontend/src/main/resources/static/console/static/js/2610.2bec9edb.js


virgo.wzfrontend/src/main/resources/static/console/static/js/2803-legacy.2eaea7fc.js → virgo.wzfrontend/src/main/resources/static/console/static/js/2803-legacy.cee27757.js


virgo.wzfrontend/src/main/resources/static/console/static/js/2877-legacy.08448b5a.js → virgo.wzfrontend/src/main/resources/static/console/static/js/2877-legacy.42676098.js


File diff suppressed because it is too large
+ 1 - 0
virgo.wzfrontend/src/main/resources/static/console/static/js/2901-legacy.6345fd4b.js


File diff suppressed because it is too large
+ 0 - 1
virgo.wzfrontend/src/main/resources/static/console/static/js/2901-legacy.e3fe6a67.js


File diff suppressed because it is too large
+ 1 - 0
virgo.wzfrontend/src/main/resources/static/console/static/js/2901.488bf607.js


File diff suppressed because it is too large
+ 0 - 1
virgo.wzfrontend/src/main/resources/static/console/static/js/2901.ca4b0230.js


File diff suppressed because it is too large
+ 1 - 1
virgo.wzfrontend/src/main/resources/static/console/static/js/2942.00b5e8d8.js


File diff suppressed because it is too large
+ 0 - 1
virgo.wzfrontend/src/main/resources/static/console/static/js/3065.2823a7d9.js


virgo.wzfrontend/src/main/resources/static/console/static/js/3099.2324eb91.js → virgo.wzfrontend/src/main/resources/static/console/static/js/3099.9b9195ae.js


File diff suppressed because it is too large
+ 1 - 0
virgo.wzfrontend/src/main/resources/static/console/static/js/3235.097d7c0e.js


File diff suppressed because it is too large
+ 1 - 0
virgo.wzfrontend/src/main/resources/static/console/static/js/3348-legacy.23718c0f.js


File diff suppressed because it is too large
+ 0 - 1
virgo.wzfrontend/src/main/resources/static/console/static/js/3401.1063831c.js


File diff suppressed because it is too large
+ 1 - 0
virgo.wzfrontend/src/main/resources/static/console/static/js/3401.34c8c8a0.js


File diff suppressed because it is too large
+ 1 - 1
virgo.wzfrontend/src/main/resources/static/console/static/js/3437-legacy.3b072752.js


File diff suppressed because it is too large
+ 1 - 1
virgo.wzfrontend/src/main/resources/static/console/static/js/3437.baa73250.js


virgo.wzfrontend/src/main/resources/static/console/static/js/3620-legacy.5f903980.js → virgo.wzfrontend/src/main/resources/static/console/static/js/3620-legacy.fc7f229f.js


virgo.wzfrontend/src/main/resources/static/console/static/js/3620.8e3783f5.js → virgo.wzfrontend/src/main/resources/static/console/static/js/3620.f11f0a7a.js


File diff suppressed because it is too large
+ 0 - 1
virgo.wzfrontend/src/main/resources/static/console/static/js/4469-legacy.35cda735.js


File diff suppressed because it is too large
+ 1 - 0
virgo.wzfrontend/src/main/resources/static/console/static/js/4469-legacy.ab1fcad8.js


virgo.wzfrontend/src/main/resources/static/console/static/js/4537-legacy.44577234.js → virgo.wzfrontend/src/main/resources/static/console/static/js/4537-legacy.1a839e7f.js


File diff suppressed because it is too large
+ 1 - 0
virgo.wzfrontend/src/main/resources/static/console/static/js/4767.9b91fcd1.js


File diff suppressed because it is too large
+ 0 - 1
virgo.wzfrontend/src/main/resources/static/console/static/js/4767.a0380d29.js


virgo.wzfrontend/src/main/resources/static/console/static/js/494-legacy.46381e87.js → virgo.wzfrontend/src/main/resources/static/console/static/js/494-legacy.56878bc6.js


virgo.wzfrontend/src/main/resources/static/console/static/js/494.e063c5d6.js → virgo.wzfrontend/src/main/resources/static/console/static/js/494.0d892db7.js


File diff suppressed because it is too large
+ 1 - 1
virgo.wzfrontend/src/main/resources/static/console/static/js/500.ae098b9d.js


File diff suppressed because it is too large
+ 0 - 1
virgo.wzfrontend/src/main/resources/static/console/static/js/5064.10cb745f.js


File diff suppressed because it is too large
+ 1 - 0
virgo.wzfrontend/src/main/resources/static/console/static/js/5064.ba118eda.js


virgo.wzfrontend/src/main/resources/static/console/static/js/5427.acd86e93.js → virgo.wzfrontend/src/main/resources/static/console/static/js/5427.c48cb0d1.js


File diff suppressed because it is too large
+ 1 - 1
virgo.wzfrontend/src/main/resources/static/console/static/js/5539.e85fc4e5.js


virgo.wzfrontend/src/main/resources/static/console/static/js/5721.7cd70eb5.js → virgo.wzfrontend/src/main/resources/static/console/static/js/5721.8ee95c98.js


File diff suppressed because it is too large
+ 1 - 1
virgo.wzfrontend/src/main/resources/static/console/static/js/5778-legacy.b2d37a05.js


File diff suppressed because it is too large
+ 1 - 1
virgo.wzfrontend/src/main/resources/static/console/static/js/5819.def2a3ed.js


File diff suppressed because it is too large
+ 0 - 1
virgo.wzfrontend/src/main/resources/static/console/static/js/6055-legacy.18a54515.js


File diff suppressed because it is too large
+ 1 - 0
virgo.wzfrontend/src/main/resources/static/console/static/js/6055-legacy.1d2c25e0.js


File diff suppressed because it is too large
+ 1 - 0
virgo.wzfrontend/src/main/resources/static/console/static/js/6235-legacy.7cda0d9b.js


File diff suppressed because it is too large
+ 0 - 1
virgo.wzfrontend/src/main/resources/static/console/static/js/6235-legacy.d4809b9b.js


File diff suppressed because it is too large
+ 1 - 0
virgo.wzfrontend/src/main/resources/static/console/static/js/6235.227a538a.js


File diff suppressed because it is too large
+ 0 - 1
virgo.wzfrontend/src/main/resources/static/console/static/js/6235.605d79f9.js


File diff suppressed because it is too large
+ 1 - 1
virgo.wzfrontend/src/main/resources/static/console/static/js/6252-legacy.6a744f5b.js


File diff suppressed because it is too large
+ 1 - 1
virgo.wzfrontend/src/main/resources/static/console/static/js/6252.6c6b0c30.js


File diff suppressed because it is too large
+ 1 - 1
virgo.wzfrontend/src/main/resources/static/console/static/js/6264-legacy.1f42bee1.js


File diff suppressed because it is too large
+ 1 - 1
virgo.wzfrontend/src/main/resources/static/console/static/js/6448.02356e97.js


File diff suppressed because it is too large
+ 1 - 1
virgo.wzfrontend/src/main/resources/static/console/static/js/6696-legacy.2e7ef363.js


File diff suppressed because it is too large
+ 1 - 1
virgo.wzfrontend/src/main/resources/static/console/static/js/6696.e38a6c82.js


File diff suppressed because it is too large
+ 0 - 1
virgo.wzfrontend/src/main/resources/static/console/static/js/7023.879c8c50.js


File diff suppressed because it is too large
+ 1 - 0
virgo.wzfrontend/src/main/resources/static/console/static/js/7023.abfd9a62.js


File diff suppressed because it is too large
+ 1 - 1
virgo.wzfrontend/src/main/resources/static/console/static/js/7072-legacy.73f348e8.js


File diff suppressed because it is too large
+ 1 - 0
virgo.wzfrontend/src/main/resources/static/console/static/js/7383-legacy.24ec2525.js


File diff suppressed because it is too large
+ 0 - 1
virgo.wzfrontend/src/main/resources/static/console/static/js/7383-legacy.4394795f.js


virgo.wzfrontend/src/main/resources/static/console/static/js/7431-legacy.1dbddc98.js → virgo.wzfrontend/src/main/resources/static/console/static/js/7431-legacy.65f70611.js


virgo.wzfrontend/src/main/resources/static/console/static/js/7431.8b50a2ae.js → virgo.wzfrontend/src/main/resources/static/console/static/js/7431.f0813df4.js


File diff suppressed because it is too large
+ 0 - 1
virgo.wzfrontend/src/main/resources/static/console/static/js/7584-legacy.4f98bac4.js


File diff suppressed because it is too large
+ 1 - 0
virgo.wzfrontend/src/main/resources/static/console/static/js/7584-legacy.b14f8558.js


File diff suppressed because it is too large
+ 0 - 1
virgo.wzfrontend/src/main/resources/static/console/static/js/7584.6e4992e5.js


File diff suppressed because it is too large
+ 1 - 0
virgo.wzfrontend/src/main/resources/static/console/static/js/7584.9c2de0b9.js


File diff suppressed because it is too large
+ 1 - 1
virgo.wzfrontend/src/main/resources/static/console/static/js/7694.1c760abe.js


File diff suppressed because it is too large
+ 1 - 1
virgo.wzfrontend/src/main/resources/static/console/static/js/7815-legacy.5ca5130f.js


File diff suppressed because it is too large
+ 1 - 1
virgo.wzfrontend/src/main/resources/static/console/static/js/7815.872a8c8b.js


File diff suppressed because it is too large
+ 0 - 1
virgo.wzfrontend/src/main/resources/static/console/static/js/8126-legacy.36f473ba.js


File diff suppressed because it is too large
+ 1 - 0
virgo.wzfrontend/src/main/resources/static/console/static/js/8126-legacy.cbd0503d.js


virgo.wzfrontend/src/main/resources/static/console/static/js/8195-legacy.4be6da3d.js → virgo.wzfrontend/src/main/resources/static/console/static/js/8195-legacy.e3b9e923.js


+ 0 - 0
virgo.wzfrontend/src/main/resources/static/console/static/js/843-legacy.a3136f8e.js


Some files were not shown because too many files changed in this diff