zhangchong 1 рік тому
батько
коміт
035e5f90bc

+ 1 - 0
index.html

@@ -12,5 +12,6 @@
 	<body>
 		<div id="app"></div>
 		<script type="module" src="/src/main.ts"></script>
+		<script type="text/javascript" src="https://api.map.baidu.com/api?v=3.0&ak=wsijQt8sLXrCW71YesmispvYHitfG9gv&s=1"></script>
 	</body>
 </html>

+ 197 - 6
package-lock.json

@@ -16,7 +16,9 @@
 				"@wangeditor/editor": "^5.1.23",
 				"@wangeditor/editor-for-vue": "^5.1.12",
 				"axios": "^1.2.0",
+				"bin-datav": "^0.2.0",
 				"echarts": "^5.4.0",
+				"echarts-gl": "^2.0.9",
 				"element-plus": "^2.2.22",
 				"file-saver": "^2.0.5",
 				"js-cookie": "^3.0.1",
@@ -194,6 +196,38 @@
 			"integrity": "sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==",
 			"dev": true
 		},
+		"node_modules/@jiaminghi/bezier-curve": {
+			"version": "0.0.9",
+			"resolved": "https://registry.npmmirror.com/@jiaminghi/bezier-curve/-/bezier-curve-0.0.9.tgz",
+			"integrity": "sha512-u9xJPOEl6Dri2E9FfmJoGxYQY7vYJkURNX04Vj64tdi535tPrpkuf9Sm0lNr3QTKdHQh0DdNRsaa62FLQNQEEw==",
+			"dependencies": {
+				"@babel/runtime": "^7.5.5"
+			}
+		},
+		"node_modules/@jiaminghi/c-render": {
+			"version": "0.4.3",
+			"resolved": "https://registry.npmmirror.com/@jiaminghi/c-render/-/c-render-0.4.3.tgz",
+			"integrity": "sha512-FJfzj5hGj7MLqqqI2D7vEzHKbQ1Ynnn7PJKgzsjXaZpJzTqs2Yw5OSeZnm6l7Qj7jyPAP53lFvEQNH4o4j6s+Q==",
+			"dependencies": {
+				"@babel/runtime": "^7.5.5",
+				"@jiaminghi/bezier-curve": "*",
+				"@jiaminghi/color": "*",
+				"@jiaminghi/transition": "*"
+			}
+		},
+		"node_modules/@jiaminghi/color": {
+			"version": "1.1.3",
+			"resolved": "https://registry.npmmirror.com/@jiaminghi/color/-/color-1.1.3.tgz",
+			"integrity": "sha512-ZY3hdorgODk4OSTbxyXBPxAxHPIVf9rPlKJyK1C1db46a50J0reFKpAvfZG8zMG3lvM60IR7Qawgcu4ZDO3+Hg=="
+		},
+		"node_modules/@jiaminghi/transition": {
+			"version": "1.1.11",
+			"resolved": "https://registry.npmmirror.com/@jiaminghi/transition/-/transition-1.1.11.tgz",
+			"integrity": "sha512-owBggipoHMikDHHDW5Gc7RZYlVuvxHADiU4bxfjBVkHDAmmck+fCkm46n2JzC3j33hWvP9nSCAeh37t6stgWeg==",
+			"dependencies": {
+				"@babel/runtime": "^7.5.5"
+			}
+		},
 		"node_modules/@jridgewell/gen-mapping": {
 			"version": "0.3.2",
 			"resolved": "https://registry.npmmirror.com/@jridgewell/gen-mapping/-/gen-mapping-0.3.2.tgz",
@@ -1280,6 +1314,19 @@
 			"integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==",
 			"dev": true
 		},
+		"node_modules/bin-datav": {
+			"version": "0.2.0",
+			"resolved": "https://registry.npmmirror.com/bin-datav/-/bin-datav-0.2.0.tgz",
+			"integrity": "sha512-msxwzGRHh+dSOBU7ELKyXkoi4vsMJq5TX8RZ3wvJcLUPfstYEUkZjBAy78ij56Cc97YH512Cvnwu1BXgXvIbNA==",
+			"dependencies": {
+				"@jiaminghi/c-render": "^0.4.3",
+				"color": "^4.2.0",
+				"resize-observer-polyfill": "^1.5.1"
+			},
+			"peerDependencies": {
+				"vue": "^3.2.20"
+			}
+		},
 		"node_modules/binary-extensions": {
 			"version": "2.2.0",
 			"resolved": "https://registry.npmmirror.com/binary-extensions/-/binary-extensions-2.2.0.tgz",
@@ -1424,6 +1471,11 @@
 				"node": ">=6.0"
 			}
 		},
+		"node_modules/claygl": {
+			"version": "1.3.0",
+			"resolved": "https://registry.npmmirror.com/claygl/-/claygl-1.3.0.tgz",
+			"integrity": "sha512-+gGtJjT6SSHD2l2yC3MCubW/sCV40tZuSs5opdtn79vFSGUgp/lH139RNEQ6Jy078/L0aV8odCw8RSrUcMfLaQ=="
+		},
 		"node_modules/clipboard": {
 			"version": "2.0.11",
 			"resolved": "https://registry.npmmirror.com/clipboard/-/clipboard-2.0.11.tgz",
@@ -1434,11 +1486,22 @@
 				"tiny-emitter": "^2.0.0"
 			}
 		},
+		"node_modules/color": {
+			"version": "4.2.3",
+			"resolved": "https://registry.npmmirror.com/color/-/color-4.2.3.tgz",
+			"integrity": "sha512-1rXeuUUiGGrykh+CeBdu5Ie7OJwinCgQY0bc7GCRxy5xVHy+moaqkpL/jqQq0MtQOeYcrqEz4abc5f0KtU7W4A==",
+			"dependencies": {
+				"color-convert": "^2.0.1",
+				"color-string": "^1.9.0"
+			},
+			"engines": {
+				"node": ">=12.5.0"
+			}
+		},
 		"node_modules/color-convert": {
 			"version": "2.0.1",
 			"resolved": "https://registry.npmmirror.com/color-convert/-/color-convert-2.0.1.tgz",
 			"integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
-			"dev": true,
 			"dependencies": {
 				"color-name": "~1.1.4"
 			},
@@ -1449,8 +1512,16 @@
 		"node_modules/color-name": {
 			"version": "1.1.4",
 			"resolved": "https://registry.npmmirror.com/color-name/-/color-name-1.1.4.tgz",
-			"integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
-			"dev": true
+			"integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA=="
+		},
+		"node_modules/color-string": {
+			"version": "1.9.1",
+			"resolved": "https://registry.npmmirror.com/color-string/-/color-string-1.9.1.tgz",
+			"integrity": "sha512-shrVawQFojnZv6xM40anx4CkoDP+fZsw/ZerEMsW/pyzsRbElpsL/DBVW7q3ExxwusdNXI3lXpuhEZkzs8p5Eg==",
+			"dependencies": {
+				"color-name": "^1.0.0",
+				"simple-swizzle": "^0.2.2"
+			}
 		},
 		"node_modules/combined-stream": {
 			"version": "1.0.8",
@@ -1612,6 +1683,18 @@
 				"zrender": "5.4.0"
 			}
 		},
+		"node_modules/echarts-gl": {
+			"version": "2.0.9",
+			"resolved": "https://registry.npmmirror.com/echarts-gl/-/echarts-gl-2.0.9.tgz",
+			"integrity": "sha512-oKeMdkkkpJGWOzjgZUsF41DOh6cMsyrGGXimbjK2l6Xeq/dBQu4ShG2w2Dzrs/1bD27b2pLTGSaUzouY191gzA==",
+			"dependencies": {
+				"claygl": "^1.2.1",
+				"zrender": "^5.1.1"
+			},
+			"peerDependencies": {
+				"echarts": "^5.1.2"
+			}
+		},
 		"node_modules/electron-to-chromium": {
 			"version": "1.4.284",
 			"resolved": "https://registry.npmmirror.com/electron-to-chromium/-/electron-to-chromium-1.4.284.tgz",
@@ -2746,6 +2829,11 @@
 			"integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==",
 			"dev": true
 		},
+		"node_modules/is-arrayish": {
+			"version": "0.3.2",
+			"resolved": "https://registry.npmmirror.com/is-arrayish/-/is-arrayish-0.3.2.tgz",
+			"integrity": "sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ=="
+		},
 		"node_modules/is-binary-path": {
 			"version": "2.1.0",
 			"resolved": "https://registry.npmmirror.com/is-binary-path/-/is-binary-path-2.1.0.tgz",
@@ -3594,6 +3682,11 @@
 			"resolved": "https://registry.npmmirror.com/requires-port/-/requires-port-1.0.0.tgz",
 			"integrity": "sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ=="
 		},
+		"node_modules/resize-observer-polyfill": {
+			"version": "1.5.1",
+			"resolved": "https://registry.npmmirror.com/resize-observer-polyfill/-/resize-observer-polyfill-1.5.1.tgz",
+			"integrity": "sha512-LwZrotdHOo12nQuZlHEmtuXdqGoOD0OhaxopaNFxWzInpEgaLWoVuAMbTzixuosCx2nEG58ngzW3vxdWoxIgdg=="
+		},
 		"node_modules/resolve": {
 			"version": "1.22.1",
 			"resolved": "https://registry.npmmirror.com/resolve/-/resolve-1.22.1.tgz",
@@ -3818,6 +3911,14 @@
 				"object-inspect": "^1.9.0"
 			}
 		},
+		"node_modules/simple-swizzle": {
+			"version": "0.2.2",
+			"resolved": "https://registry.npmmirror.com/simple-swizzle/-/simple-swizzle-0.2.2.tgz",
+			"integrity": "sha512-JA//kQgZtbuY83m+xT+tXJkmJncGMTFT+C+g2h2R9uxkYIrE2yy9sgmcLhCnw57/WSD+Eh3J97FPEDFnbXnDUg==",
+			"dependencies": {
+				"is-arrayish": "^0.3.1"
+			}
+		},
 		"node_modules/slash": {
 			"version": "3.0.0",
 			"resolved": "https://registry.npmmirror.com/slash/-/slash-3.0.0.tgz",
@@ -4615,6 +4716,38 @@
 			"integrity": "sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==",
 			"dev": true
 		},
+		"@jiaminghi/bezier-curve": {
+			"version": "0.0.9",
+			"resolved": "https://registry.npmmirror.com/@jiaminghi/bezier-curve/-/bezier-curve-0.0.9.tgz",
+			"integrity": "sha512-u9xJPOEl6Dri2E9FfmJoGxYQY7vYJkURNX04Vj64tdi535tPrpkuf9Sm0lNr3QTKdHQh0DdNRsaa62FLQNQEEw==",
+			"requires": {
+				"@babel/runtime": "^7.5.5"
+			}
+		},
+		"@jiaminghi/c-render": {
+			"version": "0.4.3",
+			"resolved": "https://registry.npmmirror.com/@jiaminghi/c-render/-/c-render-0.4.3.tgz",
+			"integrity": "sha512-FJfzj5hGj7MLqqqI2D7vEzHKbQ1Ynnn7PJKgzsjXaZpJzTqs2Yw5OSeZnm6l7Qj7jyPAP53lFvEQNH4o4j6s+Q==",
+			"requires": {
+				"@babel/runtime": "^7.5.5",
+				"@jiaminghi/bezier-curve": "*",
+				"@jiaminghi/color": "*",
+				"@jiaminghi/transition": "*"
+			}
+		},
+		"@jiaminghi/color": {
+			"version": "1.1.3",
+			"resolved": "https://registry.npmmirror.com/@jiaminghi/color/-/color-1.1.3.tgz",
+			"integrity": "sha512-ZY3hdorgODk4OSTbxyXBPxAxHPIVf9rPlKJyK1C1db46a50J0reFKpAvfZG8zMG3lvM60IR7Qawgcu4ZDO3+Hg=="
+		},
+		"@jiaminghi/transition": {
+			"version": "1.1.11",
+			"resolved": "https://registry.npmmirror.com/@jiaminghi/transition/-/transition-1.1.11.tgz",
+			"integrity": "sha512-owBggipoHMikDHHDW5Gc7RZYlVuvxHADiU4bxfjBVkHDAmmck+fCkm46n2JzC3j33hWvP9nSCAeh37t6stgWeg==",
+			"requires": {
+				"@babel/runtime": "^7.5.5"
+			}
+		},
 		"@jridgewell/gen-mapping": {
 			"version": "0.3.2",
 			"resolved": "https://registry.npmmirror.com/@jridgewell/gen-mapping/-/gen-mapping-0.3.2.tgz",
@@ -5495,6 +5628,16 @@
 			"integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==",
 			"dev": true
 		},
+		"bin-datav": {
+			"version": "0.2.0",
+			"resolved": "https://registry.npmmirror.com/bin-datav/-/bin-datav-0.2.0.tgz",
+			"integrity": "sha512-msxwzGRHh+dSOBU7ELKyXkoi4vsMJq5TX8RZ3wvJcLUPfstYEUkZjBAy78ij56Cc97YH512Cvnwu1BXgXvIbNA==",
+			"requires": {
+				"@jiaminghi/c-render": "^0.4.3",
+				"color": "^4.2.0",
+				"resize-observer-polyfill": "^1.5.1"
+			}
+		},
 		"binary-extensions": {
 			"version": "2.2.0",
 			"resolved": "https://registry.npmmirror.com/binary-extensions/-/binary-extensions-2.2.0.tgz",
@@ -5612,6 +5755,11 @@
 			"dev": true,
 			"peer": true
 		},
+		"claygl": {
+			"version": "1.3.0",
+			"resolved": "https://registry.npmmirror.com/claygl/-/claygl-1.3.0.tgz",
+			"integrity": "sha512-+gGtJjT6SSHD2l2yC3MCubW/sCV40tZuSs5opdtn79vFSGUgp/lH139RNEQ6Jy078/L0aV8odCw8RSrUcMfLaQ=="
+		},
 		"clipboard": {
 			"version": "2.0.11",
 			"resolved": "https://registry.npmmirror.com/clipboard/-/clipboard-2.0.11.tgz",
@@ -5622,11 +5770,19 @@
 				"tiny-emitter": "^2.0.0"
 			}
 		},
+		"color": {
+			"version": "4.2.3",
+			"resolved": "https://registry.npmmirror.com/color/-/color-4.2.3.tgz",
+			"integrity": "sha512-1rXeuUUiGGrykh+CeBdu5Ie7OJwinCgQY0bc7GCRxy5xVHy+moaqkpL/jqQq0MtQOeYcrqEz4abc5f0KtU7W4A==",
+			"requires": {
+				"color-convert": "^2.0.1",
+				"color-string": "^1.9.0"
+			}
+		},
 		"color-convert": {
 			"version": "2.0.1",
 			"resolved": "https://registry.npmmirror.com/color-convert/-/color-convert-2.0.1.tgz",
 			"integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
-			"dev": true,
 			"requires": {
 				"color-name": "~1.1.4"
 			}
@@ -5634,8 +5790,16 @@
 		"color-name": {
 			"version": "1.1.4",
 			"resolved": "https://registry.npmmirror.com/color-name/-/color-name-1.1.4.tgz",
-			"integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
-			"dev": true
+			"integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA=="
+		},
+		"color-string": {
+			"version": "1.9.1",
+			"resolved": "https://registry.npmmirror.com/color-string/-/color-string-1.9.1.tgz",
+			"integrity": "sha512-shrVawQFojnZv6xM40anx4CkoDP+fZsw/ZerEMsW/pyzsRbElpsL/DBVW7q3ExxwusdNXI3lXpuhEZkzs8p5Eg==",
+			"requires": {
+				"color-name": "^1.0.0",
+				"simple-swizzle": "^0.2.2"
+			}
 		},
 		"combined-stream": {
 			"version": "1.0.8",
@@ -5765,6 +5929,15 @@
 				"zrender": "5.4.0"
 			}
 		},
+		"echarts-gl": {
+			"version": "2.0.9",
+			"resolved": "https://registry.npmmirror.com/echarts-gl/-/echarts-gl-2.0.9.tgz",
+			"integrity": "sha512-oKeMdkkkpJGWOzjgZUsF41DOh6cMsyrGGXimbjK2l6Xeq/dBQu4ShG2w2Dzrs/1bD27b2pLTGSaUzouY191gzA==",
+			"requires": {
+				"claygl": "^1.2.1",
+				"zrender": "^5.1.1"
+			}
+		},
 		"electron-to-chromium": {
 			"version": "1.4.284",
 			"resolved": "https://registry.npmmirror.com/electron-to-chromium/-/electron-to-chromium-1.4.284.tgz",
@@ -6575,6 +6748,11 @@
 			"integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==",
 			"dev": true
 		},
+		"is-arrayish": {
+			"version": "0.3.2",
+			"resolved": "https://registry.npmmirror.com/is-arrayish/-/is-arrayish-0.3.2.tgz",
+			"integrity": "sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ=="
+		},
 		"is-binary-path": {
 			"version": "2.1.0",
 			"resolved": "https://registry.npmmirror.com/is-binary-path/-/is-binary-path-2.1.0.tgz",
@@ -7230,6 +7408,11 @@
 			"resolved": "https://registry.npmmirror.com/requires-port/-/requires-port-1.0.0.tgz",
 			"integrity": "sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ=="
 		},
+		"resize-observer-polyfill": {
+			"version": "1.5.1",
+			"resolved": "https://registry.npmmirror.com/resize-observer-polyfill/-/resize-observer-polyfill-1.5.1.tgz",
+			"integrity": "sha512-LwZrotdHOo12nQuZlHEmtuXdqGoOD0OhaxopaNFxWzInpEgaLWoVuAMbTzixuosCx2nEG58ngzW3vxdWoxIgdg=="
+		},
 		"resolve": {
 			"version": "1.22.1",
 			"resolved": "https://registry.npmmirror.com/resolve/-/resolve-1.22.1.tgz",
@@ -7387,6 +7570,14 @@
 				"object-inspect": "^1.9.0"
 			}
 		},
+		"simple-swizzle": {
+			"version": "0.2.2",
+			"resolved": "https://registry.npmmirror.com/simple-swizzle/-/simple-swizzle-0.2.2.tgz",
+			"integrity": "sha512-JA//kQgZtbuY83m+xT+tXJkmJncGMTFT+C+g2h2R9uxkYIrE2yy9sgmcLhCnw57/WSD+Eh3J97FPEDFnbXnDUg==",
+			"requires": {
+				"is-arrayish": "^0.3.1"
+			}
+		},
 		"slash": {
 			"version": "3.0.0",
 			"resolved": "https://registry.npmmirror.com/slash/-/slash-3.0.0.tgz",

+ 2 - 0
package.json

@@ -20,7 +20,9 @@
 		"@wangeditor/editor": "^5.1.23",
 		"@wangeditor/editor-for-vue": "^5.1.12",
 		"axios": "^1.2.0",
+		"bin-datav": "^0.2.0",
 		"echarts": "^5.4.0",
+		"echarts-gl": "^2.0.9",
 		"element-plus": "^2.2.22",
 		"file-saver": "^2.0.5",
 		"js-cookie": "^3.0.1",

+ 5 - 1
src/main.ts

@@ -16,6 +16,10 @@ import Empty from '/@/components/Empty/index.vue';
 // 图片预览
 import 'viewerjs/dist/viewer.css';
 import VueViewer from 'v-viewer';
+// 引入大屏组件库
+// @ts-ignore
+import BinDatav from 'bin-datav';
+import 'bin-datav/lib/styles/index.css';
 
 const app = createApp(App);
 
@@ -30,6 +34,6 @@ other.elSvg(app);
 app.component('Pagination', Pagination)
 app.component('Empty', Empty);
 
-app.use(pinia).use(router).use(ElementPlus).use(VueViewer).mount('#app');
+app.use(pinia).use(router).use(ElementPlus).use(VueViewer).use(BinDatav).mount('#app');
 
 

+ 17 - 1
src/router/route.ts

@@ -120,5 +120,21 @@ export const staticRoutes: Array<RouteRecordRaw> = [
 		meta: {
 			title: '重置密码',
 		},
-	}
+	},
+	{
+		path: '/visualizingDemo1',
+		name: 'visualizingDemo1',
+		component: () => import('/@/views/visualizing/demo1.vue'),
+		meta: {
+			title: '大屏展示1',
+		},
+	},
+	{
+		path: '/visualizingDemo2',
+		name: 'visualizingDemo2',
+		component: () => import('/@/views/visualizing/demo2.vue'),
+		meta: {
+			title: '大屏展示2',
+		},
+	},
 ];

+ 0 - 6
src/views/knowledge/knowledge/component/knowledge-edit.vue

@@ -369,8 +369,6 @@ const getKnowledgeType = async () => {
 };
 onMounted(async () => {
 	await getKnowledgeType();
-	state.loading = true;
-	try {
 		if (route.params.id) {
 			const res: any = await KnowledgeDetail(route.params.id); //知识详情
 			if (route.params.isDraft) {
@@ -382,10 +380,6 @@ onMounted(async () => {
 				state.hotspotExternal = state.ruleForm.hotspotExternal.split(',');
 			}
 			state.ruleForm.knowledges = state.ruleForm.knowledges ?? [];
-			state.loading = false;
 		}
-	} catch (error) {
-		state.loading = false;
-	}
 });
 </script>

+ 109 - 107
src/views/tels/blacklist/component/Blacklist-add.vue

@@ -1,141 +1,143 @@
 <template>
-    <div class="system-blacklist-add-container">
-        <el-dialog v-model="state.isShowDialog" width="500px" draggable title="新增黑名单">
-            <el-form :model="state.ruleForm" ref="blacklistFormRef" label-width="80px" label-position="left">
-                <el-row :gutter="35">
-                    <el-col :xs="24" :sm="24" :md="24" :lg="24" :xl="24">
-                        <el-form-item label="电话号码" prop="phoneNo" :rules="[{ required: true, message: '请输入电话号码', trigger: 'blur' }
-                        ]">
-                            <el-input v-model="state.ruleForm.phoneNo" placeholder="请输入电话号码" clearable></el-input>
-                        </el-form-item>
-                    </el-col>
-                    <el-col :xs="24" :sm="24" :md="24" :lg="24" :xl="24">
-                        <el-form-item label="级别" prop="level" :rules="[{ required: true, message: '请选择级别', trigger: 'change' }]">
-                            <template #label>
-                                <div class="flex-center-align">级别
-                                    <el-popover :width="500" trigger="hover">
-                                        <template #reference>
-                                            <SvgIcon name="ele-QuestionFilled" color="var(--el-color-info)" class="ml5"/>
-                                        </template>
-                                        <div>
-                                            <p>呼入限制:接通后直接挂断</p>
-                                            <p>坐席限制:可进入IVR,可使用语音导航功能以及智能机器人(如有),不支持转人工服务,语音导航中屏蔽转人工选项</p>
-                                            <p>友情提示:接通后,播放礼貌性提示语后挂断(提示语在呼叫中心配置),提示语内容由业务设定</p>
-                                        </div>
-                                    </el-popover>
-                                </div>
-                            </template>
-                            <el-select v-model="state.ruleForm.level" placeholder="请选择级别" class="w100">
-                                <el-option v-for="item in state.levelList" :key="item.value" :label="item.label"
-                                    :value="item.value" />
-                            </el-select>
-                        </el-form-item>
-                    </el-col>
-                    <!-- <el-col :xs="24" :sm="24" :md="24" :lg="24" :xl="24">
-                        <el-form-item label="黑名单时长(秒)" prop="duration"
-                            :rules="[{ required: true, message: '请输入时间(秒)', trigger: 'blur' }]">
-                            <el-input-number v-model="state.ruleForm.duration" :precision="0" :min="1" class="w100" />
-                        </el-form-item>
-                    </el-col> -->
-                    <el-col :xs="24" :sm="24" :md="24" :lg="24" :xl="24">
-                        <el-form-item label="时间" prop="time"
-                            :rules="[{ required: true, message: '请选择时间', trigger: 'change' }]">
-                            <el-date-picker
-                                v-model="state.ruleForm.time"
-                                type="datetimerange"
-                                range-separator="至"
-                                start-placeholder="开始时间"
-                                end-placeholder="结束时间"
-                                value-format="YYYY-MM-DD[T]HH:mm:ss"
-                            />
-                        </el-form-item>
-                    </el-col>
-                    <el-col :xs="24" :sm="12" :md="24" :lg="24" :xl="24">
-						<el-form-item label="情况说明" prop="remark" :rules="[{ required: true, message: '请输入情况说明', trigger: 'blur' }]">
-							<el-input v-model="state.ruleForm.remark" type="textarea" :autosize="{ minRows: 4, maxRows: 6 }" placeholder="请输入情况说明" clearable></el-input>
+	<div class="system-blacklist-add-container">
+		<el-dialog v-model="state.isShowDialog" width="500px" draggable title="新增黑名单">
+			<el-form :model="state.ruleForm" ref="blacklistFormRef" label-width="80px" label-position="left">
+				<el-row :gutter="35">
+					<el-col :xs="24" :sm="24" :md="24" :lg="24" :xl="24">
+						<el-form-item label="电话号码" prop="phoneNo" :rules="[{ required: true, message: '请输入电话号码', trigger: 'blur' }]">
+							<el-input v-model="state.ruleForm.phoneNo" placeholder="请输入电话号码" clearable></el-input>
 						</el-form-item>
 					</el-col>
-                </el-row>
-            </el-form>
-            <template #footer>
-                <span class="dialog-footer">
-                    <el-button @click="closeDialog" class="default-button">取 消</el-button>
-                    <el-button type="primary" @click="onSubmit">保 存</el-button>
-                </span>
-            </template>
-        </el-dialog>
-    </div>
+<!--					<el-col :xs="24" :sm="24" :md="24" :lg="24" :xl="24">-->
+<!--						<el-form-item label="级别" prop="level" :rules="[{ required: true, message: '请选择级别', trigger: 'change' }]">-->
+<!--							<template #label>-->
+<!--								<div class="flex-center-align">-->
+<!--									级别-->
+<!--									<el-popover :width="500" trigger="hover">-->
+<!--										<template #reference>-->
+<!--											<SvgIcon name="ele-QuestionFilled" color="var(&#45;&#45;el-color-info)" class="ml5" />-->
+<!--										</template>-->
+<!--										<div>-->
+<!--											<p>呼入限制:接通后直接挂断</p>-->
+<!--											<p>坐席限制:可进入IVR,可使用语音导航功能以及智能机器人(如有),不支持转人工服务,语音导航中屏蔽转人工选项</p>-->
+<!--											<p>友情提示:接通后,播放礼貌性提示语后挂断(提示语在呼叫中心配置),提示语内容由业务设定</p>-->
+<!--										</div>-->
+<!--									</el-popover>-->
+<!--								</div>-->
+<!--							</template>-->
+<!--							<el-select v-model="state.ruleForm.level" placeholder="请选择级别" class="w100">-->
+<!--								<el-option v-for="item in state.levelList" :key="item.value" :label="item.label" :value="item.value" />-->
+<!--							</el-select>-->
+<!--						</el-form-item>-->
+<!--					</el-col>-->
+					<el-col :xs="24" :sm="24" :md="24" :lg="24" :xl="24">
+						<el-form-item label="黑名单时长(秒)" prop="duration" :rules="[{ required: true, message: '请输入时间(秒)', trigger: 'blur' }]">
+							<el-input-number v-model="state.ruleForm.duration" :precision="0" :min="1" class="w100" />
+						</el-form-item>
+					</el-col>
+<!--					<el-col :xs="24" :sm="24" :md="24" :lg="24" :xl="24">-->
+<!--						<el-form-item label="时间" prop="time" :rules="[{ required: true, message: '请选择时间', trigger: 'change' }]">-->
+<!--							<el-date-picker-->
+<!--								v-model="state.ruleForm.time"-->
+<!--								type="datetimerange"-->
+<!--								range-separator="至"-->
+<!--								start-placeholder="开始时间"-->
+<!--								end-placeholder="结束时间"-->
+<!--								value-format="YYYY-MM-DD[T]HH:mm:ss"-->
+<!--							/>-->
+<!--						</el-form-item>-->
+<!--					</el-col>-->
+<!--					<el-col :xs="24" :sm="12" :md="24" :lg="24" :xl="24">-->
+<!--						<el-form-item label="情况说明" prop="remark" :rules="[{ required: true, message: '请输入情况说明', trigger: 'blur' }]">-->
+<!--							<el-input-->
+<!--								v-model="state.ruleForm.remark"-->
+<!--								type="textarea"-->
+<!--								:autosize="{ minRows: 4, maxRows: 6 }"-->
+<!--								placeholder="请输入情况说明"-->
+<!--								clearable-->
+<!--							></el-input>-->
+<!--						</el-form-item>-->
+<!--					</el-col>-->
+				</el-row>
+			</el-form>
+			<template #footer>
+				<span class="dialog-footer">
+					<el-button @click="closeDialog" class="default-button">取 消</el-button>
+					<el-button type="primary" @click="onSubmit">保 存</el-button>
+				</span>
+			</template>
+		</el-dialog>
+	</div>
 </template>
 
 <script lang="ts" setup name="blackAdd">
-import { ref, reactive} from 'vue';
+import { ref, reactive } from 'vue';
 import { ElMessage } from 'element-plus';
 import { addBlacklist } from '/@/api/tels/blacklist';
 
 // 定义接口来定义对象的类型
 interface StateBlacklist {
-    ruleForm: {
-        phoneNo: string; //电话号码
-        level: string; //级别
-        time:Array<any>; // 时间
-        remark:string; //清空说明
-    }
-    isShowDialog: boolean;
-    levelList: Array<any>; // 级别列表
+	ruleForm: {
+		phoneNo: string; //电话号码
+		level: string; //级别
+		time: Array<any>; // 时间
+		remark: string; //清空说明
+	};
+	isShowDialog: boolean;
+	levelList: Array<any>; // 级别列表
 }
 
 // 定义子组件向父组件传值/事件
-const emit = defineEmits(['updateList', 'openDialog', 'closeDialog'])
+const emit = defineEmits(['updateList', 'openDialog', 'closeDialog']);
 
 // 定义变量内容
 const blacklistFormRef = ref<RefType>();
-const state = reactive<StateBlacklist>({
-    ruleForm: {
-        phoneNo: "",
-        level:'',
-        time:[],
-        remark:''
-    },
-    isShowDialog: false,
-    levelList: [
+const state = reactive<any>({
+	ruleForm: {
+		phoneNo: '',
+    duration:0,
+	},
+	isShowDialog: false,
+	levelList: [
 		{
 			label: '呼入限制',
-			value: 0
+			value: 0,
 		},
 		{
 			label: '坐席限制',
-			value: 1
-		},{
+			value: 1,
+		},
+		{
 			label: '友情提示',
-			value: 2
+			value: 2,
 		},
 	],
-})
+});
 // 打开弹窗
 const openDialog = () => {
-    blacklistFormRef.value?.resetFields();
-    state.isShowDialog = true;
-    emit('openDialog')
-}
+	blacklistFormRef.value?.resetFields();
+	state.isShowDialog = true;
+	emit('openDialog');
+};
 // 关闭弹窗
 const closeDialog = () => {
-    state.isShowDialog = false;
-    emit('closeDialog')
+	state.isShowDialog = false;
+	emit('closeDialog');
 };
 // 新增保存
 const onSubmit = () => {
-    blacklistFormRef.value.validate((valid: boolean) => {
-        if (valid) {
-            addBlacklist(state.ruleForm).then(() => {
-                ElMessage.success("新增成功")
-                emit("updateList");
-                state.isShowDialog = false;
-            })
-        } else {
-            return false;
-        }
-    });
-}
+	blacklistFormRef.value.validate((valid: boolean) => {
+		if (valid) {
+			addBlacklist(state.ruleForm).then(() => {
+				ElMessage.success('新增成功');
+				emit('updateList');
+				state.isShowDialog = false;
+			});
+		} else {
+			return false;
+		}
+	});
+};
 //暴漏变量和方法
-defineExpose({ closeDialog, openDialog })
+defineExpose({ closeDialog, openDialog });
 </script>

+ 3 - 3
src/views/tels/blacklist/index.vue

@@ -39,9 +39,9 @@
 					<el-button type="primary" @click="onAddBlacklist" v-waves v-auth="'tels:blackList:add'">
 						<SvgIcon name="ele-Plus" class="mr5" />新增
 					</el-button>
-					<el-button type="primary" @click="onRemove" v-waves v-auth="'tels:blackList:delete'" :disabled="!state.multipleSelection.length">
-						<SvgIcon name="ele-Delete" class="mr5" />解除
-					</el-button>
+<!--					<el-button type="primary" @click="onRemove" v-waves v-auth="'tels:blackList:delete'" :disabled="!state.multipleSelection.length">-->
+<!--						<SvgIcon name="ele-Delete" class="mr5" />解除-->
+<!--					</el-button>-->
 				</div>
 			</div>
 			<!-- 表格 -->

+ 1247 - 0
src/views/visualizing/demo1.vue

@@ -0,0 +1,1247 @@
+<template>
+	<div class="visualizing-demo1">
+		<div class="visualizing-container">
+			<!-- 头部 -->
+			<div class="visualizing-container-head">
+				<div class="visualizing-container-head-left">
+					<div class="visualizing-container-head-left-text">
+						<div class="visualizing-container-head-left-text-box">{{ state.time.txt }}</div>
+					</div>
+				</div>
+				<div class="visualizing-container-head-center">
+					<div class="visualizing-container-head-center-box">
+						<div class="visualizing-container-head-center-mainTitle">宜宾市12345数据展示</div>
+					</div>
+				</div>
+				<div class="visualizing-container-head-right">
+					<div class="visualizing-container-head-right-text">
+						<div class="visualizing-container-head-right-text-box">🌤 多云转晴东南风 26~30℃</div>
+					</div>
+				</div>
+			</div>
+
+			<!-- 图表左侧 -->
+			<div class="visualizing-container-content-left">
+				<div class="visualizing-container-content-left-flex boxBg">
+					<div class="visualizing-container-title">
+						<i class="el-icon-s-shop"></i>
+						<span>受理工单概览</span>
+					</div>
+					<bv-scroll-table :config="config" class="mt5" style="width: 100%; height: 100%"></bv-scroll-table>
+				</div>
+				<div class="visualizing-container-content-left-flex boxBg">
+					<div class="visualizing-container-title">
+						<i class="el-icon-s-promotion"></i>
+						<span>问题类型统计</span>
+					</div>
+					<div ref="visualizingContentLeftBottom" style="height: 100%"></div>
+				</div>
+				<div class="visualizing-container-content-left-flex boxBg">
+					<div class="visualizing-container-title">
+						<i class="el-icon-s-shop"></i>
+						<span>部门案件办理情况</span>
+					</div>
+					<div ref="visualizingContentLeftTop" style="height: 100%"></div>
+				</div>
+				<div class="visualizing-container-content-left-flex boxBg">
+					<div class="visualizing-container-title">
+						<i class="el-icon-s-promotion"></i>
+						<span>问题高发 TOP5</span>
+					</div>
+					<div ref="visualizingContentLeftBottom" style="height: 100%"></div>
+				</div>
+			</div>
+
+			<!-- 图表中间 -->
+			<div class="visualizing-container-content-center">
+				<div class="visualizing-container-content-center-top">
+					<bv-border-box name="border2" class="visualizing-container-content-center-top-box"
+						><p class="visualizing-container-content-center-top-box-title">今日案件总数</p>
+						<p class="visualizing-container-content-center-top-box-value colorful1">
+							<bv-count-to :startVal="0" :endVal="18" ref="countTo" separator=""></bv-count-to>
+						</p>
+					</bv-border-box>
+					<bv-border-box name="border2" class="visualizing-container-content-center-top-box"
+						><p class="visualizing-container-content-center-top-box-title">正在办理</p>
+						<p class="visualizing-container-content-center-top-box-value colorful2">
+							<bv-count-to :startVal="0" :endVal="2" ref="countTo" separator=""></bv-count-to>
+						</p>
+					</bv-border-box>
+					<bv-border-box name="border2" class="visualizing-container-content-center-top-box"
+						><p class="visualizing-container-content-center-top-box-title">已办案件</p>
+						<p class="visualizing-container-content-center-top-box-value colorful3">
+							<bv-count-to :startVal="0" :endVal="16" ref="countTo" separator=""></bv-count-to>
+						</p>
+					</bv-border-box>
+					<bv-border-box name="border2" class="visualizing-container-content-center-top-box"
+						><p class="visualizing-container-content-center-top-box-title">本年接件量</p>
+						<p class="visualizing-container-content-center-top-box-value colorful4">
+							<bv-count-to :startVal="0" :endVal="1007" ref="countTo" separator=""></bv-count-to>
+						</p>
+					</bv-border-box>
+					<bv-border-box name="border2" class="visualizing-container-content-center-top-box"
+						><p class="visualizing-container-content-center-top-box-title">本年办结量</p>
+						<p class="visualizing-container-content-center-top-box-value colorful5">
+							<bv-count-to :startVal="0" :endVal="987" ref="countTo" separator=""></bv-count-to>
+						</p>
+					</bv-border-box>
+					<bv-border-box name="border2" class="visualizing-container-content-center-top-box"
+						><p class="visualizing-container-content-center-top-box-title">累计接件量</p>
+						<p class="visualizing-container-content-center-top-box-value colorful6">
+							<bv-count-to :startVal="0" :endVal="1345123" ref="countTo" separator=""></bv-count-to>
+						</p>
+					</bv-border-box>
+				</div>
+				<!-- 地图 -->
+				<div class="visualizing-container-content-center-middle">
+					<div ref="visualizingDemo1" style="height: 100%"></div>
+				</div>
+				<div class="visualizing-container-content-center-bottom boxBg">
+					<div class="visualizing-container-title">
+						<i class="el-icon-s-flag"></i>
+						<span>办理情况 TOP5</span>
+					</div>
+					<div ref="visualizingContentCenterBottom" style="height: 100%"></div>
+				</div>
+			</div>
+
+			<!-- 图表右侧 -->
+			<div class="visualizing-container-content-right">
+				<div class="visualizing-container-content-right-flex boxBg">
+					<div class="visualizing-container-title">
+						<i class="el-icon-s-marketing"></i>
+						<span>办件状态分析</span>
+					</div>
+					<div ref="visualizingContentRightTop" style="height: 100%"></div>
+				</div>
+				<div class="visualizing-container-content-right-flex boxBg">
+					<div class="visualizing-container-title">
+						<i class="el-icon-s-data"></i>
+						<span>坐席话务实况</span>
+					</div>
+					<div ref="visualizingContentRightBottom" style="height: 100%"></div>
+				</div>
+				<div class="visualizing-container-content-right-flex boxBg">
+					<div class="visualizing-container-title">
+						<i class="el-icon-s-data"></i>
+						<span>来源占比分析</span>
+					</div>
+					<div ref="visualizingContentRightBottom" style="height: 100%"></div>
+				</div>
+				<div class="visualizing-container-content-right-flex boxBg">
+					<div class="visualizing-container-title">
+						<i class="el-icon-s-data"></i>
+						<span>投诉热词</span>
+					</div>
+					<div ref="visualizingContentRightBottom" style="height: 100%"></div>
+				</div>
+			</div>
+		</div>
+	</div>
+</template>
+
+<script setup lang="ts" name="visualizingLinkDemo1">
+import { onMounted, onUnmounted, reactive, ref } from 'vue';
+import * as echarts from 'echarts';
+import 'echarts/extension/bmap/bmap';
+import { formatDate } from '/@/utils/formatTime';
+import { NextLoading } from '/@/utils/loading';
+import { echartsMapData, echartsMapImgs, echartsMapList } from './mock/demo1';
+import Watermark from '/@/utils/watermark';
+
+// 定义变量内容
+const visualizingDemo1 = ref();
+const visualizingContentLeftTop = ref();
+const visualizingContentLeftBottom = ref();
+const visualizingContentCenterBottom = ref();
+const visualizingContentRightTop = ref();
+const visualizingContentRightBottom = ref();
+const state = reactive({
+	echartsMapList,
+	echartsMapData,
+	echartsMapImgs,
+	time: {
+		txt: '',
+		fun: 0,
+	},
+	myCharts: [] as EmptyArrayType,
+});
+
+// 初始化时间
+const initTime = () => {
+	state.time.txt = formatDate(new Date(), 'YYYY-mm-dd HH:MM:SS WWW QQQQ ZZZ');
+	state.time.fun = window.setInterval(() => {
+		state.time.txt = formatDate(new Date(), 'YYYY-mm-dd HH:MM:SS WWW QQQQ ZZZ');
+	}, 1000);
+};
+// echartsMap 将坐标信息和对应物理量的值合在一起
+const convertData = (data: any) => {
+	let res = [];
+	for (let i = 0; i < data.length; i++) {
+		let geoCoord = state.echartsMapData[data[i].name];
+		if (geoCoord) {
+			res.push({
+				name: data[i].name,
+				value: geoCoord.concat(data[i].value),
+			});
+		}
+	}
+	return res;
+};
+//
+const config = reactive({
+	header: ['列1', '列2', '列3'],
+	data: [
+		['行1列1', '行1列2', '行1列3'],
+		['行2列1', '行2列2', '行2列3'],
+		['行3列1', '行3列2', '行3列3'],
+		['行4列1', '行4列2', '行4列3'],
+		['行5列1', '行5列2', '行5列3'],
+		['行6列1', '行6列2', '行6列3'],
+		['行7列1', '行7列2', '行7列3'],
+		['行8列1', '行8列2', '行8列3'],
+		['行9列1', '行9列2', '行9列3'],
+		['行10列1', '行10列2', '行10列3'],
+	],
+	headerBGC: 'rgba(0, 0, 0, .3)',
+	oddRowBGC: 'rgba(25, 140, 139, 0.1)',
+	evenRowBGC: 'rgba(25, 140, 139, 0.2)',
+});
+// 初始化 echartsMap(地图上的点)
+const initEchartsMap = () => {
+	const myChart = echarts.init(<HTMLElement>visualizingDemo1.value);
+	const option = {
+		tooltip: {
+			trigger: 'item',
+			formatter(params: any) {
+				// 自定义鼠标放入样式
+				let item = state.echartsMapImgs.find((v: any) => v.name === params.name);
+				return `<div style="width: 240px;">
+							<div style="display: flex; align-items: center">
+								<img src="${item?.url}" style="width: 50px; height: 50px; border-radius: 100%; position: relative; border: 4px solid #ffffff; margin-left: -4px"  alt=""/>
+								<div
+									style="
+										background: #51c1ff;
+										width: 100%;
+										height: 32px;
+										display: flex;
+										margin-left: -14px;
+										align-items: center;
+										padding-left: 20px;
+										color: #fff;
+									"
+								>
+									${item?.name}
+								</div>
+							</div>
+							<div style="margin-top: 10px; font-size: 12px">
+								<div style="width: 61px"><i class="el-icon-location-information" style="margin-right: 5px"></i>地址:</div>
+								<div style="flex: 1; white-space: pre-wrap; word-break: break-all; margin-top: 5px; color: #333">${item?.add}</div>
+							</div>
+							<div style="margin-top: 10px; font-size: 12px">
+								<div style="width: 61px"><i class="el-icon-chat-dot-round" style="margin-right: 5px"></i>概括:</div>
+								<div style="flex: 1; white-space: pre-wrap; word-break: break-all; margin-top: 5px; color: #333">${item?.dec}</div>
+							</div>
+						</div>`;
+			},
+		},
+		color: ['#ea7ccc'],
+		bmap: {
+			center: [114.064524, 22.549225],
+			zoom: 11,
+			roam: true,
+			mapStyle: {},
+		},
+		series: [
+			{
+				name: '门票收入',
+				type: 'scatter',
+				coordinateSystem: 'bmap',
+				data: convertData(state.echartsMapList),
+				symbolSize: function (val: any) {
+					return val[2] / 10;
+				},
+				encode: {
+					value: 2,
+				},
+				label: {
+					formatter: '{b}',
+					position: 'right',
+					show: false,
+				},
+				emphasis: {
+					label: {
+						show: true,
+					},
+				},
+			},
+			{
+				name: '门票收入',
+				type: 'effectScatter',
+				coordinateSystem: 'bmap',
+				data: convertData(
+					state.echartsMapList
+						.sort(function (a: any, b: any) {
+							return b.value - a.value;
+						})
+						.slice(0, 6)
+				),
+				symbolSize: function (val: any) {
+					return val[2] / 10;
+				},
+				encode: {
+					value: 2,
+				},
+				showEffectOn: 'render',
+				rippleEffect: {
+					brushType: 'stroke',
+				},
+				hoverAnimation: true,
+				label: {
+					formatter: '{b}',
+					position: 'right',
+					show: true,
+				},
+				itemStyle: {
+					shadowBlur: 100,
+					shadowColor: '#333',
+				},
+				zlevel: 1,
+			},
+		],
+	};
+	myChart.setOption(option);
+	state.myCharts.push(myChart);
+
+	// 地图
+	const map = (<any>myChart).getModel().getComponent('bmap').getBMap();
+	// BMAP_NORMAL_MAP :此地图类型展示普通街道视图
+	// BMAP_PERSPECTIVE_MAP :此地图类型展示透视图像视图。(这个还不会用)
+	// BMAP_SATELLITE_MAP:卫星地图 (没有坐标, 绿绿的一片的卫星地图)
+	// BMAP_HYBRID_MAP:混合地图 (既有坐标,也是绿绿的一片的卫星地图)
+	// eslint-disable-next-line no-undef
+	map.setMapType(BMAP_SATELLITE_MAP);
+	// eslint-disable-next-line no-undef
+	let bdary = new BMap.Boundary();
+	// 获取行政区域
+	bdary.get('深圳', function (rs: any) {
+		// 行政区域的点有多少个
+		let count = rs.boundaries.length;
+		for (let i = 0; i < count; i++) {
+			// eslint-disable-next-line no-undef
+			let ply = new BMap.Polygon(rs.boundaries[i], {
+				// 设置多边形边线线粗
+				strokeWeight: 4,
+				// 设置多边形边线透明度0-1
+				strokeOpacity: 1,
+				// 设置多边形边线样式为实线或虚线,取值 solid 或 dashed
+				StrokeStyle: 'dashed',
+				// 设置多边形边线颜色
+				strokeColor: '#febb50',
+				// 设置多边形填充颜色
+				fillColor: '',
+			});
+			// 建立多边形覆盖物
+			// 添加覆盖物
+			map.addOverlay(ply);
+			// 调整视野
+			map.setViewport(ply.getPath());
+		}
+		// 初始化地图,设置中心点坐标和地图级别
+		// new BMap.Point('深圳市', 11)
+		// eslint-disable-next-line no-undef
+		map.centerAndZoom(new BMap.Point(114.064524, 22.549225), 11);
+	});
+};
+// 产业概况
+const initVisualizingContentLeftTop = () => {
+	const myChart = echarts.init(visualizingContentLeftTop.value);
+	const option = {
+		grid: {
+			top: 50,
+			right: 0,
+			bottom: 50,
+			left: 30,
+		},
+		tooltip: {
+			trigger: 'axis',
+		},
+		xAxis: {
+			data: ['1月', '2月', '3月', '4月', '5月', '6月'],
+			axisLine: {
+				lineStyle: {
+					color: 'rgba(22, 207, 208, 0.1)',
+					width: 1,
+				},
+			},
+			axisTick: {
+				show: false,
+			},
+			axisLabel: {
+				color: '#16cfd0',
+			},
+		},
+		yAxis: [
+			{
+				type: 'value',
+				name: '价格',
+				axisLine: {
+					show: true,
+					lineStyle: {
+						color: 'rgba(22, 207, 208, 0.1)',
+					},
+				},
+				axisLabel: {
+					color: '#16cfd0',
+				},
+				splitLine: {
+					show: true,
+					lineStyle: {
+						color: 'rgba(22, 207, 208, 0.3)',
+					},
+				},
+				splitArea: {
+					show: true,
+					areaStyle: {
+						color: 'rgba(22, 207, 208, 0.02)',
+					},
+				},
+				nameTextStyle: {
+					color: '#16cfd0',
+				},
+			},
+		],
+		series: [
+			{
+				name: '预购队列',
+				type: 'line',
+				data: [200, 85, 112, 275, 305, 415],
+				itemStyle: {
+					color: '#16cfd0',
+				},
+			},
+			{
+				name: '最新成交价',
+				type: 'line',
+				data: [50, 85, 22, 155, 170, 25],
+				itemStyle: {
+					color: '#febb50',
+				},
+			},
+		],
+	};
+	myChart.setOption(option);
+	state.myCharts.push(myChart);
+};
+// A级风景区对比
+const initVisualizingContentLeftBottom = () => {
+	const myChart = echarts.init(visualizingContentLeftBottom.value);
+	const option = {
+		grid: {
+			top: 10,
+			right: 10,
+			bottom: 40,
+			left: 30,
+		},
+		tooltip: {
+			trigger: 'axis',
+		},
+		xAxis: {
+			type: 'category',
+			boundaryGap: false,
+			data: ['1月', '2月', '3月', '4月', '5月'],
+			axisLine: {
+				lineStyle: {
+					color: 'rgba(22, 207, 208, 0.1)',
+					width: 1,
+				},
+			},
+			axisTick: {
+				show: false,
+			},
+			axisLabel: {
+				interval: 0,
+				color: '#16cfd0',
+				textStyle: {
+					fontSize: 10,
+				},
+			},
+		},
+		yAxis: [
+			{
+				type: 'value',
+				name: '销量',
+				axisLabel: {
+					color: '#16cfd0',
+				},
+				splitLine: {
+					show: true,
+					lineStyle: {
+						color: 'rgba(22, 207, 208, 0.3)',
+					},
+				},
+				splitArea: {
+					show: true,
+					areaStyle: {
+						color: 'rgba(22, 207, 208, 0.02)',
+					},
+				},
+				nameTextStyle: {
+					color: '#16cfd0',
+				},
+			},
+		],
+		series: [
+			{
+				name: '客流',
+				type: 'line',
+				stack: '总量',
+				smooth: true,
+				lineStyle: {
+					width: 0,
+				},
+				areaStyle: {
+					opacity: 0.8,
+					color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
+						{
+							offset: 0,
+							color: 'rgba(128, 255, 165)',
+						},
+						{
+							offset: 1,
+							color: 'rgba(1, 191, 236)',
+						},
+					]),
+				},
+				emphasis: {
+					focus: 'series',
+				},
+				data: [140, 232, 101, 264, 90],
+			},
+			{
+				name: '天数',
+				type: 'line',
+				stack: '总量',
+				smooth: true,
+				lineStyle: {
+					width: 0,
+				},
+				areaStyle: {
+					opacity: 0.8,
+					color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
+						{
+							offset: 0,
+							color: 'rgba(0, 221, 255)',
+						},
+						{
+							offset: 1,
+							color: 'rgba(77, 119, 255)',
+						},
+					]),
+				},
+				emphasis: {
+					focus: 'series',
+				},
+				data: [120, 282, 111, 234, 220],
+			},
+		],
+	};
+	myChart.setOption(option);
+	state.myCharts.push(myChart);
+};
+// 游客驻留时长
+const initVisualizingContentCenterBottom = () => {
+	const myChart = echarts.init(visualizingContentCenterBottom.value);
+	const option = {
+		tooltip: {
+			trigger: 'axis',
+			axisPointer: {
+				type: 'shadow',
+			},
+		},
+		grid: {
+			top: 26,
+			right: 10,
+			bottom: 66,
+			left: 45,
+		},
+		xAxis: {
+			type: 'value',
+			axisLabel: {
+				color: '#16cfd0',
+			},
+			splitLine: {
+				show: true,
+				lineStyle: {
+					color: 'rgba(22, 207, 208, 0.3)',
+				},
+			},
+		},
+		yAxis: {
+			type: 'category',
+			axisLabel: {
+				color: '#16cfd0',
+			},
+		},
+		series: [
+			{
+				name: '已完成',
+				type: 'bar',
+				stack: 'total',
+				label: {
+					show: true,
+				},
+				emphasis: {
+					focus: 'series',
+				},
+				barWidth: 12,
+				itemStyle: {
+					label: {
+						show: true,
+					},
+					labelLine: {
+						show: false,
+					},
+					color: new echarts.graphic.LinearGradient(0, 0, 1, 0, [
+						{ offset: 0, color: 'rgba(7,165,255,0.2)' },
+						{ offset: 1, color: 'rgba(7,165,255,1)' },
+					]),
+				},
+			},
+			{
+				name: '进行中',
+				type: 'bar',
+				stack: 'total',
+				label: {
+					show: true,
+				},
+				emphasis: {
+					focus: 'series',
+				},
+				barWidth: 12,
+				itemStyle: {
+					label: {
+						show: true,
+					},
+					labelLine: {
+						show: false,
+					},
+					color: new echarts.graphic.LinearGradient(0, 0, 1, 0, [
+						{ offset: 0, color: 'rgba(41,244,236,0)' },
+						{ offset: 1, color: 'rgba(41,244,236,1)' },
+					]),
+				},
+			},
+		],
+		dataset: {
+			source: [
+				{ status: '已签收', value1: 33, value2: 93 },
+				{ status: '配送中', value1: 53, value2: 32 },
+				{ status: '已出库', value1: 78, value2: 65 },
+				{ status: '采购中', value1: 12, value2: 35 },
+				{ status: '接单中', value1: 90, value2: 52 },
+			],
+		},
+	};
+	myChart.setOption(option);
+	state.myCharts.push(myChart);
+};
+// 当日游客趋势分析
+const initVisualizingContentRightTop = () => {
+	const myChart = echarts.init(visualizingContentRightTop.value);
+	const option = {
+		grid: {
+			top: 50,
+			right: 30,
+			bottom: 50,
+			left: 20,
+		},
+		tooltip: {
+			trigger: 'axis',
+			axisPointer: {
+				type: 'shadow',
+			},
+		},
+		xAxis: {
+			data: ['1月', '2月', '3月', '4月', '5月', '6月'],
+			axisLine: {
+				lineStyle: {
+					color: 'rgba(22, 207, 208, 0.5)',
+					width: 1,
+				},
+			},
+			axisTick: {
+				show: false,
+			},
+			axisLabel: {
+				color: '#16cfd0',
+			},
+		},
+		yAxis: [
+			{
+				type: 'value',
+				name: '亿元',
+				axisLine: {
+					show: true,
+					lineStyle: {
+						color: 'rgba(22, 207, 208, 0.1)',
+					},
+				},
+				axisLabel: {
+					color: '#16cfd0',
+				},
+				splitLine: {
+					show: true,
+					lineStyle: {
+						color: 'rgba(22, 207, 208, 0.3)',
+					},
+				},
+				splitArea: {
+					show: true,
+					areaStyle: {
+						color: 'rgba(22, 207, 208, 0.02)',
+					},
+				},
+				nameTextStyle: {
+					color: '#16cfd0',
+				},
+			},
+			{
+				type: 'value',
+				name: '同比',
+				position: 'right',
+				axisLine: {
+					show: false,
+				},
+				axisLabel: {
+					show: true,
+					formatter: '{value}%',
+					textStyle: {
+						color: '#16cfd0',
+					},
+				},
+				splitLine: {
+					show: false,
+				},
+				axisTick: {
+					show: false,
+				},
+				splitArea: {
+					show: true,
+					areaStyle: {
+						color: 'rgba(22, 207, 208, 0.02)',
+					},
+				},
+				nameTextStyle: {
+					color: '#16cfd0',
+				},
+			},
+		],
+		series: [
+			{
+				name: '销售水量',
+				type: 'line',
+				yAxisIndex: 1,
+				smooth: true,
+				showAllSymbol: true,
+				symbol: 'circle',
+				itemStyle: {
+					color: '#058cff',
+				},
+				lineStyle: {
+					color: '#058cff',
+				},
+				areaStyle: {
+					color: 'rgba(5,140,255, 0.2)',
+				},
+				data: [4.2, 3.8, 4.8, 3.5, 2.9, 2.8],
+			},
+			{
+				name: '主营业务',
+				type: 'bar',
+				barWidth: 15,
+				itemStyle: {
+					normal: {
+						color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
+							{
+								offset: 0,
+								color: '#00FFE3',
+							},
+							{
+								offset: 1,
+								color: '#4693EC',
+							},
+						]),
+					},
+				},
+				data: [4.2, 3.8, 4.8, 3.5, 2.9, 2.8],
+			},
+		],
+	};
+	myChart.setOption(option);
+	state.myCharts.push(myChart);
+};
+// 当月游客趋势分析
+const initVisualizingContentRightBottom = () => {
+	const myChart = echarts.init(visualizingContentRightBottom.value);
+	const option = {
+		grid: {
+			top: 50,
+			right: 10,
+			bottom: 40,
+			left: 30,
+		},
+		tooltip: {
+			trigger: 'axis',
+		},
+		xAxis: {
+			data: ['1月', '2月', '3月', '4月', '5月', '6月'],
+			axisLine: {
+				lineStyle: {
+					color: 'rgba(22, 207, 208, 0.1)',
+					width: 1,
+				},
+			},
+			axisTick: {
+				show: false,
+			},
+			axisLabel: {
+				color: '#16cfd0',
+			},
+		},
+		yAxis: [
+			{
+				type: 'value',
+				name: '人数(万)',
+				axisLine: {
+					show: true,
+					lineStyle: {
+						color: 'rgba(22, 207, 208, 0.1)',
+					},
+				},
+				axisLabel: {
+					color: '#16cfd0',
+				},
+				splitLine: {
+					show: true,
+					lineStyle: {
+						color: 'rgba(22, 207, 208, 0.3)',
+					},
+				},
+				splitArea: {
+					show: true,
+					areaStyle: {
+						color: 'rgba(22, 207, 208, 0.02)',
+					},
+				},
+				nameTextStyle: {
+					color: '#16cfd0',
+				},
+			},
+		],
+		series: [
+			{
+				name: '预购队列',
+				type: 'line',
+				data: [20, 15, 40, 55, 65, 85],
+				smooth: true,
+				itemStyle: {
+					color: '#EA7CCC',
+				},
+			},
+			{
+				name: '最新成交价',
+				type: 'line',
+				data: [30, 45, 65, 85, 60, 105],
+				smooth: true,
+				itemStyle: {
+					color: '#FAC958',
+				},
+			},
+		],
+	};
+	myChart.setOption(option);
+	state.myCharts.push(myChart);
+};
+// 批量设置 echarts resize
+const initEchartsResize = () => {
+	window.addEventListener('resize', () => {
+		for (let i = 0; i < state.myCharts.length; i++) {
+			state.myCharts[i].resize();
+		}
+	});
+};
+// 页面加载时
+onMounted(async () => {
+	NextLoading.done();
+	initTime();
+	await initEchartsMap();
+	await initVisualizingContentLeftTop();
+	await initVisualizingContentLeftBottom();
+	await initVisualizingContentCenterBottom();
+	await initVisualizingContentRightTop();
+	await initVisualizingContentRightBottom();
+	await initEchartsResize();
+	Watermark.del(); // 清除水印
+});
+// 页面卸载时
+onUnmounted(() => {
+	window.clearInterval(state.time.fun);
+});
+</script>
+
+<style scoped lang="scss">
+// 左右两侧图表宽度
+$lrWidth: 467px;
+// 中部底部图表高度
+$cbHeight: calc(25% - 23px);
+// 中部顶部图标高度
+$ctHeight: 68px;
+// 标题宽度
+$titleWidth: 240px;
+// 盒子之间的间距
+$boxSpace: 7px;
+// 盒子背景样式
+.boxBg {
+	background: rgba(6, 64, 63, 0.6);
+	box-shadow: 0 5px 45px 5px #06130b;
+	border: 2px solid rgba(41, 211, 212, 0.2);
+	padding: 5px 15px;
+}
+.visualizing-demo1 {
+	height: 100%;
+	width: 100%;
+	position: relative;
+	background-color: #06130b;
+	:deep(.BMap_cpyCtrl) {
+		display: none;
+	}
+	:deep(.anchorBL) {
+		display: none;
+	}
+	.visualizing-container {
+		.visualizing-container-head {
+			height: 60px;
+			width: 100%;
+			position: absolute;
+			top: 0;
+			left: 0;
+			display: flex;
+			align-items: center;
+			color: #ffffff;
+			background: linear-gradient(to bottom, rgba(0, 0, 0, 0.9), rgba(0, 0, 0, 0.3), rgba(0, 0, 0, 0.02));
+			z-index: 3;
+			.visualizing-container-head-left {
+				flex: 1;
+				position: relative;
+				height: 60px;
+				.visualizing-container-head-left-text {
+					position: relative;
+					z-index: 1;
+					font-size: 12px;
+					opacity: 0.6;
+					width: 93%;
+					padding-left: 15px;
+					top: 50%;
+					transform: translateY(-100%);
+					.visualizing-container-head-left-text-box {
+						width: 100%;
+						position: relative;
+						padding-left: 15px;
+						&::after {
+							content: '';
+							height: 20px;
+							width: 100%;
+							position: absolute;
+							background: linear-gradient(to right, rgba(22, 207, 208, 0.1), rgba(22, 207, 208, 0.3));
+							top: -1px;
+							left: 0;
+							transform: skew(30deg);
+						}
+					}
+				}
+				&::before,
+				&::after {
+					content: '';
+					height: 3px;
+					background: linear-gradient(-90deg, #16cfd0, transparent);
+					position: absolute;
+					width: 100%;
+				}
+				&::before {
+					top: 1px;
+					right: 33px;
+					opacity: 0.8;
+				}
+				&::after {
+					top: 41px;
+					right: -2px;
+				}
+			}
+			.visualizing-container-head-center {
+				height: 60px;
+				font-size: 18px;
+				text-align: center;
+				display: flex;
+				flex-direction: column;
+				position: relative;
+				padding: 0 60px;
+				background: radial-gradient(rgba(0, 0, 0, 0.7) 5%, rgba(0, 0, 0, 0.5) 15%, rgba(0, 0, 0, 0.02) 70%);
+				.visualizing-container-head-center-box {
+					margin: auto;
+					position: relative;
+					z-index: 1;
+					.visualizing-container-head-center-mainTitle {
+						position: relative;
+
+						font-size: 36px;
+						font-weight: bold;
+						color: #d3dbeb;
+
+						background: linear-gradient(0deg, #dafaff 0%, #00726c 100%);
+						-webkit-background-clip: text;
+						-webkit-text-fill-color: transparent;
+						&::before,
+						&::after {
+							content: '';
+							position: absolute;
+							min-width: 21%;
+							height: 29px;
+							top: 2px;
+							opacity: 0.3;
+							border-top: 1px solid #16cfd0;
+						}
+						&::before {
+							left: -70px;
+							border-right: 2px solid #16cfd0;
+							transform: skew(50deg);
+						}
+						&::after {
+							right: -70px;
+							border-left: 2px solid #16cfd0;
+							transform: skew(-50deg);
+						}
+					}
+					&::before,
+					&::after {
+						content: '';
+						position: absolute;
+						width: 36px;
+						height: 17px;
+						top: -8px;
+						border-bottom: 2px solid rgba(22, 207, 208, 0.7);
+					}
+					&::before {
+						transform: skew(32deg);
+						left: -89px;
+						border-left: 3px solid rgba(22, 207, 208, 0.7);
+					}
+					&::after {
+						transform: skew(-32deg);
+						right: -89px;
+						border-right: 3px solid rgba(22, 207, 208, 0.7);
+					}
+				}
+				&::before,
+				&::after {
+					content: '';
+					position: absolute;
+					min-width: 50%;
+					height: 15px;
+					bottom: 0;
+					border-bottom: 4px solid #16cfd0;
+				}
+				&::before {
+					transform: skew(60deg);
+					left: 13px;
+					border-left: 5px solid #16cfd0;
+				}
+				&::after {
+					transform: skew(-60deg);
+					right: 13px;
+					border-right: 5px solid #16cfd0;
+				}
+			}
+			.visualizing-container-head-right {
+				flex: 1;
+				position: relative;
+				height: 60px;
+				.visualizing-container-head-right-text {
+					position: relative;
+					z-index: 1;
+					font-size: 12px;
+					opacity: 0.6;
+					width: 93%;
+					float: right;
+					text-align: right;
+					padding-right: 15px;
+					top: 50%;
+					transform: translateY(-100%);
+					.visualizing-container-head-right-text-box {
+						width: 100%;
+						position: relative;
+						padding-right: 15px;
+						&::after {
+							content: '';
+							height: 20px;
+							width: 100%;
+							position: absolute;
+							background: linear-gradient(to left, rgba(22, 207, 208, 0.1), rgba(22, 207, 208, 0.3));
+							top: -1px;
+							right: 0;
+							transform: skew(-30deg);
+						}
+					}
+				}
+				&::before,
+				&::after {
+					content: '';
+					height: 3px;
+					background: linear-gradient(90deg, #16cfd0, transparent);
+					position: absolute;
+					width: 100%;
+				}
+				&::before {
+					top: 1px;
+					left: 33px;
+					opacity: 0.8;
+				}
+				&::after {
+					top: 41px;
+					left: -2px;
+				}
+			}
+		}
+		.visualizing-container-title {
+			max-width: $titleWidth;
+			font-size: 16px;
+			font-weight: bold;
+			color: #ffffff;
+			background: linear-gradient(0deg, #ffffff 0%, #8ccaca 100%);
+			-webkit-background-clip: text;
+			-webkit-text-fill-color: transparent;
+			i {
+				padding-right: 5px;
+				color: orange;
+			}
+		}
+		.visualizing-container-content-left {
+			width: $lrWidth;
+			height: 100%;
+			position: absolute;
+			top: 0;
+			left: 0;
+			background: linear-gradient(to right, rgba(0, 0, 0, 0.9), rgba(0, 0, 0, 0.5), rgba(0, 0, 0, 0.01));
+			padding-top: 60px;
+			z-index: 2;
+			display: flex;
+			flex-direction: column;
+			.visualizing-container-content-left-flex {
+				flex: 1;
+				display: flex;
+				flex-direction: column;
+				margin-left: $boxSpace;
+				margin-bottom: $boxSpace;
+			}
+		}
+		.visualizing-container-content-center {
+			width: 100%;
+			background: linear-gradient(to top, rgba(0, 0, 0, 0.9), rgba(0, 0, 0, 0.5), rgba(0, 0, 0, 0.01));
+			z-index: 1;
+			.visualizing-container-content-center-top {
+				width: calc(100% - #{$lrWidth * 2});
+				height: $ctHeight;
+				left: $lrWidth;
+				top: 60px;
+				position: absolute;
+				display: flex;
+				padding: 0 $boxSpace;
+				.visualizing-container-content-center-top-box {
+					text-align: center;
+					flex: 1;
+					margin: 0 $boxSpace;
+					.visualizing-container-content-center-top-box-title {
+						color: #bdd9d9;
+						font-size: 14px;
+						padding-top: 9px;
+					}
+					.visualizing-container-content-center-top-box-value {
+						font-size: 28px;
+						font-weight: bold;
+					}
+					.colorful1 {
+						color: #d1904b;
+						background: linear-gradient(0deg, #fff846 28.6865234375%, #ffffff 100%);
+						-webkit-background-clip: text;
+						-webkit-text-fill-color: transparent;
+					}
+					.colorful2 {
+						color: #5896e2;
+						background: linear-gradient(0deg, #53a0ff 28.6865234375%, #ffffff 100%);
+						-webkit-background-clip: text;
+						-webkit-text-fill-color: transparent;
+					}
+					.colorful3 {
+						color: #2ffdfd;
+						background: linear-gradient(0deg, #dafaff 0%, #30ae48 100%);
+						-webkit-background-clip: text;
+						-webkit-text-fill-color: transparent;
+					}
+					.colorful4 {
+						color: #179090;
+						background: linear-gradient(0deg, #dafaff 0%, #00726c 100%);
+						-webkit-background-clip: text;
+						-webkit-text-fill-color: transparent;
+					}
+					.colorful5 {
+						color: #179090;
+						background: linear-gradient(0deg, #dafaff 0%, #00726c 100%);
+						-webkit-background-clip: text;
+						-webkit-text-fill-color: transparent;
+					}
+					.colorful6 {
+						color: #179090;
+						background: linear-gradient(0deg, #dafaff 0%, #00726c 100%);
+						-webkit-background-clip: text;
+						-webkit-text-fill-color: transparent;
+					}
+				}
+			}
+			.visualizing-container-content-center-middle {
+				position: absolute;
+				left: $lrWidth;
+				top: calc(60px + #{$ctHeight});
+				right: $lrWidth;
+				bottom: calc(#{$cbHeight} + #{$boxSpace});
+			}
+			.visualizing-container-content-center-bottom {
+				width: calc(100% - #{$lrWidth * 2} - #{$boxSpace * 2});
+				height: $cbHeight;
+				left: $lrWidth;
+				bottom: 0;
+				position: absolute;
+				margin: 0 $boxSpace $boxSpace $boxSpace;
+			}
+		}
+		.visualizing-container-content-right {
+			width: $lrWidth;
+			height: 100%;
+			position: absolute;
+			top: 0;
+			right: 0;
+			padding-top: 60px;
+			display: flex;
+			flex-direction: column;
+			background: linear-gradient(to left, rgba(0, 0, 0, 0.9), rgba(0, 0, 0, 0.5), rgba(0, 0, 0, 0.01));
+			z-index: 2;
+			.visualizing-container-content-right-flex {
+				display: flex;
+				flex-direction: column;
+				margin-right: $boxSpace;
+				flex: 1;
+				margin-bottom: $boxSpace;
+			}
+		}
+	}
+}
+</style>

+ 1340 - 0
src/views/visualizing/demo2.vue

@@ -0,0 +1,1340 @@
+<template>
+	<div class="visualizing-demo2">
+		<!-- 顶部 -->
+		<div class="big-data-up">
+			<div class="up-left">
+				<SvgIcon name="ele-Timer" class="mr5" />
+				<span>{{ state.time.txt }}</span>
+			</div>
+			<div class="up-center">
+				<span>智慧农业系统平台</span>
+			</div>
+			<div class="up-right">
+				<el-dropdown size="small">
+					<span class="el-dropdown-link">
+						{{ state.dropdownActive }}
+						<SvgIcon name="ele-ArrowDown" class="el-icon--right" />
+					</span>
+					<template #dropdown>
+						<el-dropdown-menu>
+							<el-dropdown-item v-for="(v, k) in state.dropdownList" :key="k">{{ v.label }} </el-dropdown-item>
+						</el-dropdown-menu>
+					</template>
+				</el-dropdown>
+				<div class="ml15">
+					<SvgIcon name="ele-Bell" class="mr5" />
+					<span>消息</span>
+				</div>
+				<div class="ml15">
+					<SvgIcon name="ele-User" class="mr5" />
+					<span>个人</span>
+				</div>
+				<div class="ml15">
+					<SvgIcon name="ele-SwitchButton" class="mr5" />
+					<span>返回</span>
+				</div>
+			</div>
+		</div>
+
+		<div class="big-data-down">
+			<!-- 左边 -->
+			<div class="big-data-down-left">
+				<div class="flex-warp-item">
+					<div class="flex-warp-item-box">
+						<div class="flex-title">天气预报</div>
+						<div class="flex-content flex-content-overflow">
+							<div class="sky">
+								<SvgIcon name="ele-Sunny" class="sky-left" />
+								<div class="sky-center">
+									<div class="mb2">
+										<span class="font">多云转晴</span>
+										<span class="font">东南风</span>
+										<span>良</span>
+									</div>
+									<div class="sky-tip">温馨提示:多云转晴,南风转北风风力3级</div>
+								</div>
+								<div class="sky-right">
+									<span>25</span>
+									<span class="font">°C</span>
+								</div>
+							</div>
+							<div class="sky-dd">
+								<div class="sky-dl" v-for="(v, k) in state.skyList" :key="k" :class="{ 'sky-dl-first': k === 1 }">
+									<div>{{ v.v1 }}</div>
+									<div v-if="v.type === 'title'">{{ v.v2 }}</div>
+									<div v-else>
+										<SvgIcon :name="v.v2" />
+									</div>
+									<div>{{ v.v3 }}</div>
+									<div>{{ v.v4 }}</div>
+									<div class="tip">{{ v.v5 }}</div>
+									<div>{{ v.v6 }}</div>
+									<div>{{ v.v7 }}</div>
+								</div>
+							</div>
+						</div>
+					</div>
+				</div>
+				<div class="flex-warp-item">
+					<div class="flex-warp-item-box">
+						<div class="flex-title">当前设备状态</div>
+						<div class="flex-content flex-content-overflow">
+							<div class="d-states">
+								<div class="d-states-item">
+									<SvgIcon name="ele-Odometer" class="i-bg1" />
+									<div class="d-states-flex">
+										<div class="d-states-item-label">园区设备数</div>
+										<div class="d-states-item-value">99</div>
+									</div>
+								</div>
+								<div class="d-states-item">
+									<SvgIcon name="ele-FirstAidKit" class="i-bg2" />
+									<div class="d-states-flex">
+										<div class="d-states-item-label">预警设备数</div>
+										<div class="d-states-item-value">10</div>
+									</div>
+								</div>
+								<div class="d-states-item">
+									<SvgIcon name="ele-VideoPlay" class="i-bg3" />
+									<div class="d-states-flex">
+										<div class="d-states-item-label">运行设备数</div>
+										<div class="d-states-item-value">20</div>
+									</div>
+								</div>
+							</div>
+							<div class="d-btn">
+								<div class="d-btn-item" v-for="(v, k) in state.dBtnList" :key="k" :class="{ 'd-btn-active': state.dBtnActive === k }">
+									<SvgIcon name="ele-Money" class="d-btn-item-left" />
+									<div class="d-btn-item-center">
+										<div>{{ v.v1 }}</div>
+										<div>{{ v.v2 }}|{{ v.v3 }}</div>
+									</div>
+									<div class="d-btn-item-eight">{{ v.v4 }}</div>
+								</div>
+							</div>
+						</div>
+					</div>
+				</div>
+				<div class="flex-warp-item">
+					<div class="flex-warp-item-box">
+						<div class="flex-title">近30天预警总数</div>
+						<div class="flex-content" ref="rightChartData1"></div>
+					</div>
+				</div>
+			</div>
+
+			<!-- 中间 -->
+			<div class="big-data-down-center">
+				<div class="big-data-down-center-one">
+					<div class="big-data-down-center-one-content" ref="rightChartData5">
+						<div id="3DEarth"></div>
+						<div :class="v.topLevelClass" v-for="(v, k) in state.earth3DBtnList" :key="k">
+							<div class="circle" v-for="i in 4" :key="i"></div>
+							<div class="text-box">
+								<SvgIcon :name="v.icon" :size="22" />
+								<div class="text">{{ v.label }}</div>
+							</div>
+						</div>
+					</div>
+				</div>
+				<div class="big-data-down-center-two">
+					<div class="flex-warp-item-box">
+						<div class="flex-title">
+							<span>当前设备监测</span>
+							<span class="flex-title-small">单位:次</span>
+						</div>
+						<div class="flex-content">
+							<div class="flex-content-left">
+								<div class="monitor-item" v-for="(v, k) in state.chartData4List" :key="k">
+									<div class="monitor-wave" :class="{ 'monitor-active': k === state.chartData4Index }">
+										<div class="monitor-z-index">
+											<div class="monitor-item-label">{{ v.label }}</div>
+										</div>
+									</div>
+								</div>
+							</div>
+							<div class="flex-content-right" ref="rightChartData4"></div>
+						</div>
+					</div>
+				</div>
+			</div>
+
+			<!-- 右边 -->
+			<div class="big-data-down-right">
+				<div class="flex-warp-item">
+					<div class="flex-warp-item-box">
+						<div class="flex-title">
+							<span>近7天产品追溯扫码统计</span>
+							<span class="flex-title-small">单位:次</span>
+						</div>
+						<div class="flex-content" ref="rightChartData3"></div>
+					</div>
+				</div>
+				<div class="flex-warp-item">
+					<div class="flex-warp-item-box">
+						<div class="flex-title">当前任务统计</div>
+						<div class="flex-content">
+							<div class="task">
+								<div class="task-item task-first-item">
+									<div class="task-item-value task-first">25</div>
+									<div class="task-item-label">待办任务</div>
+								</div>
+								<div class="task-item">
+									<div class="task-item-box task1">
+										<div class="task-item-value">12</div>
+										<div class="task-item-label">施肥</div>
+									</div>
+								</div>
+								<div class="task-item">
+									<div class="task-item-box task2">
+										<div class="task-item-value">3</div>
+										<div class="task-item-label">施药</div>
+									</div>
+								</div>
+								<div class="task-item">
+									<div class="task-item-box task3">
+										<div class="task-item-value">5</div>
+										<div class="task-item-label">农事</div>
+									</div>
+								</div>
+								<div class="task-item">
+									<div class="task-item-box task4">
+										<div class="task-item-value">3</div>
+										<div class="task-item-label">巡园</div>
+									</div>
+								</div>
+								<div class="task-item">
+									<div class="task-item-box task5">
+										<div class="task-item-value">2</div>
+										<div class="task-item-label">采集</div>
+									</div>
+								</div>
+							</div>
+							<div ref="rightChartData6" class="progress"></div>
+						</div>
+					</div>
+				</div>
+				<div class="flex-warp-item">
+					<div class="flex-warp-item-box">
+						<div class="flex-title">
+							<span>近7天投入品记录</span>
+							<span class="flex-title-small">单位:件</span>
+						</div>
+						<div class="flex-content" ref="rightChartData2"></div>
+					</div>
+				</div>
+			</div>
+		</div>
+	</div>
+</template>
+
+<script setup lang="ts" name="visualizingLinkDemo2">
+import { reactive, onMounted, onUnmounted, ref } from 'vue';
+import * as echarts from 'echarts';
+import 'echarts-gl';
+import { formatDate } from '/@/utils/formatTime';
+import { NextLoading } from '/@/utils/loading';
+import { dropdownList, skyList, dBtnList, earth3DBtnList, chartData4List } from './mock/demo2';
+
+// 定义变量内容
+const rightChartData1 = ref();
+const rightChartData2 = ref();
+const rightChartData3 = ref();
+const rightChartData4 = ref();
+const rightChartData5 = ref();
+const rightChartData6 = ref();
+const state = reactive<Demo2State>({
+	time: {
+		txt: '',
+		fun: 0,
+	},
+	dropdownList,
+	dropdownActive: '请选择',
+	skyList,
+	dBtnList,
+	chartData4Index: 0,
+	dBtnActive: 0,
+	earth3DBtnList,
+	chartData4List,
+	myCharts: [],
+});
+
+// 初始化时间
+const initTime = () => {
+	state.time.txt = formatDate(new Date(), 'YYYY-mm-dd HH:MM:SS WWW QQQQ ZZZ');
+	state.time.fun = window.setInterval(() => {
+		state.time.txt = formatDate(new Date(), 'YYYY-mm-dd HH:MM:SS WWW QQQQ ZZZ');
+	}, 1000);
+};
+// 近30天预警总数
+const initRightChartData1 = () => {
+	const myChart = echarts.init(rightChartData1.value);
+	const option = {
+		tooltip: {
+			trigger: 'item',
+		},
+		series: [
+			{
+				name: '面积模式',
+				type: 'pie',
+				radius: [10, 60],
+				center: ['50%', '50%'],
+				roseType: 'area',
+				itemStyle: {
+					borderRadius: 5,
+				},
+				data: [
+					{ name: '天气预警', value: 100 },
+					{ name: '病虫害预警', value: 50 },
+					{ name: '任务预警', value: 130 },
+					{ name: '监测设备预警', value: 62 },
+				],
+				label: {
+					color: '#c0d1f2',
+				},
+			},
+		],
+	};
+	myChart.setOption(option);
+	state.myCharts.push(myChart);
+};
+// 当前设备监测
+const initRightChartData4 = () => {
+	const myChart = echarts.init(rightChartData4.value);
+	const option = {
+		grid: {
+			top: 10,
+			right: 10,
+			bottom: 20,
+			left: 30,
+		},
+		tooltip: {
+			trigger: 'axis',
+		},
+		xAxis: {
+			type: 'category',
+			boundaryGap: false,
+			data: ['1月', '2月', '3月', '4月', '5月', '6月'],
+			axisLine: {
+				lineStyle: {
+					color: 'rgba(22, 207, 208, 0.1)',
+					width: 1,
+				},
+			},
+			axisTick: {
+				show: false,
+			},
+			axisLabel: {
+				interval: 0,
+				color: '#c0d1f2',
+				textStyle: {
+					fontSize: 10,
+				},
+			},
+		},
+		yAxis: [
+			{
+				type: 'value',
+				axisLabel: {
+					color: '#c0d1f2',
+				},
+				splitLine: {
+					show: true,
+					lineStyle: {
+						color: 'rgba(22, 207, 208, 0.3)',
+					},
+				},
+				splitArea: {
+					show: true,
+					areaStyle: {
+						color: 'rgba(22, 207, 208, 0.02)',
+					},
+				},
+				nameTextStyle: {
+					color: '#16cfd0',
+				},
+			},
+		],
+		series: [
+			{
+				name: '温度',
+				type: 'line',
+				smooth: true,
+				lineStyle: {
+					width: 0,
+				},
+				areaStyle: {
+					opacity: 0.8,
+					color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
+						{
+							offset: 0,
+							color: 'rgba(128, 255, 165)',
+						},
+						{
+							offset: 1,
+							color: 'rgba(1, 191, 236)',
+						},
+					]),
+				},
+				emphasis: {
+					focus: 'series',
+				},
+				data: [140, 232, 101, 264, 90, 70],
+			},
+		],
+	};
+	myChart.setOption(option);
+	state.myCharts.push(myChart);
+};
+// 近7天产品追溯扫码统计
+const initRightChartData3 = () => {
+	const myChart = echarts.init(rightChartData3.value);
+	const option = {
+		grid: {
+			top: 10,
+			right: 0,
+			bottom: 20,
+			left: 30,
+		},
+		tooltip: {
+			trigger: 'axis',
+		},
+		xAxis: {
+			data: ['1月', '2月', '3月', '4月', '5月', '6月'],
+			axisLine: {
+				lineStyle: {
+					color: 'rgba(22, 207, 208, 0.1)',
+					width: 1,
+				},
+			},
+			axisTick: {
+				show: false,
+			},
+			axisLabel: {
+				color: '#c0d1f2',
+			},
+		},
+		yAxis: [
+			{
+				type: 'value',
+				axisLine: {
+					show: true,
+					lineStyle: {
+						color: 'rgba(22, 207, 208, 0.1)',
+					},
+				},
+				axisLabel: {
+					color: '#c0d1f2',
+				},
+				splitLine: {
+					show: true,
+					lineStyle: {
+						color: 'rgba(22, 207, 208, 0.3)',
+					},
+				},
+				splitArea: {
+					show: true,
+					areaStyle: {
+						color: 'rgba(22, 207, 208, 0.02)',
+					},
+				},
+				nameTextStyle: {
+					color: '#16cfd0',
+				},
+			},
+		],
+		series: [
+			{
+				name: '预购队列',
+				type: 'line',
+				data: [200, 85, 112, 275, 305, 415],
+				itemStyle: {
+					color: '#16cfd0',
+				},
+			},
+			{
+				name: '最新成交价',
+				type: 'line',
+				data: [50, 85, 22, 155, 170, 25],
+				itemStyle: {
+					color: '#febb50',
+				},
+			},
+		],
+	};
+	myChart.setOption(option);
+	state.myCharts.push(myChart);
+};
+// 当前任务统计
+const initRightChartData6 = () => {
+	const myChart = echarts.init(rightChartData6.value);
+	const option = {
+		tooltip: {
+			trigger: 'axis',
+			axisPointer: {
+				type: 'shadow',
+			},
+		},
+		grid: {
+			top: 20,
+			right: 50,
+			bottom: 0,
+			left: 80,
+		},
+		xAxis: [
+			{
+				splitLine: {
+					show: false,
+				},
+				type: 'value',
+				show: false,
+			},
+		],
+		yAxis: [
+			{
+				splitLine: {
+					show: false,
+				},
+				axisLine: {
+					//y轴
+					show: false,
+				},
+				type: 'category',
+				axisTick: {
+					show: false,
+				},
+				inverse: true,
+				data: ['施肥任务完成率', '施药任务完成率', '农事任务完成率'],
+				axisLabel: {
+					color: '#A7D6F4',
+					fontSize: 12,
+				},
+			},
+		],
+		series: [
+			{
+				name: '标准化',
+				type: 'bar',
+				barWidth: 10, // 柱子宽度
+				label: {
+					show: true,
+					position: 'right', // 位置
+					color: '#A7D6F4',
+					fontSize: 12,
+					distance: 15, // 距离
+					formatter: '{c}%', // 这里是数据展示的时候显示的数据
+				}, // 柱子上方的数值
+				itemStyle: {
+					barBorderRadius: [0, 20, 20, 0], // 圆角(左上、右上、右下、左下)
+
+					color: new echarts.graphic.LinearGradient(
+						1,
+						0,
+						0,
+						0,
+						[
+							{
+								offset: 0,
+								color: '#51C5FD',
+							},
+							{
+								offset: 1,
+								color: '#005BB1',
+							},
+						],
+						false
+					), // 渐变
+				},
+				data: [75, 100, 60],
+			},
+		],
+	};
+	myChart.setOption(option);
+	state.myCharts.push(myChart);
+};
+// 近7天投入品记录
+const initRightChartData2 = () => {
+	const myChart = echarts.init(rightChartData2.value);
+	const option = {
+		grid: {
+			top: 10,
+			right: 0,
+			bottom: 20,
+			left: 30,
+		},
+		tooltip: {
+			trigger: 'axis',
+			axisPointer: {
+				type: 'shadow',
+			},
+		},
+		xAxis: {
+			data: ['1月', '2月', '3月', '4月', '5月', '6月'],
+			axisLine: {
+				lineStyle: {
+					color: 'rgba(22, 207, 208, 0.5)',
+					width: 1,
+				},
+			},
+			axisTick: {
+				show: false,
+			},
+			axisLabel: {
+				color: '#c0d1f2',
+			},
+		},
+		yAxis: [
+			{
+				type: 'value',
+				axisLine: {
+					show: true,
+					lineStyle: {
+						color: 'rgba(22, 207, 208, 0.1)',
+					},
+				},
+				axisLabel: {
+					color: '#c0d1f2',
+				},
+				splitLine: {
+					show: true,
+					lineStyle: {
+						color: 'rgba(22, 207, 208, 0.3)',
+					},
+				},
+				splitArea: {
+					show: true,
+					areaStyle: {
+						color: 'rgba(22, 207, 208, 0.02)',
+					},
+				},
+				nameTextStyle: {
+					color: '#16cfd0',
+				},
+			},
+			{
+				type: 'value',
+				position: 'right',
+				axisLine: {
+					show: false,
+				},
+				axisLabel: {
+					show: true,
+					formatter: '{value}%',
+					textStyle: {
+						color: '#16cfd0',
+					},
+				},
+				splitLine: {
+					show: false,
+				},
+				axisTick: {
+					show: false,
+				},
+				splitArea: {
+					show: true,
+					areaStyle: {
+						color: 'rgba(22, 207, 208, 0.02)',
+					},
+				},
+				nameTextStyle: {
+					color: '#16cfd0',
+				},
+			},
+		],
+		series: [
+			{
+				name: '销售水量',
+				type: 'line',
+				yAxisIndex: 1,
+				smooth: true,
+				showAllSymbol: true,
+				symbol: 'circle',
+				itemStyle: {
+					color: '#058cff',
+				},
+				lineStyle: {
+					color: '#058cff',
+				},
+				areaStyle: {
+					color: 'rgba(5,140,255, 0.2)',
+				},
+				data: [4.2, 3.8, 4.8, 3.5, 2.9, 2.8],
+			},
+			{
+				name: '主营业务',
+				type: 'bar',
+				barWidth: 15,
+				itemStyle: {
+					normal: {
+						color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
+							{
+								offset: 0,
+								color: '#00FFE3',
+							},
+							{
+								offset: 1,
+								color: '#4693EC',
+							},
+						]),
+					},
+				},
+				data: [4.2, 3.8, 4.8, 3.5, 2.9, 2.8],
+			},
+		],
+	};
+	myChart.setOption(option);
+	state.myCharts.push(myChart);
+};
+// 3DEarth 地图
+const init3DEarth = (globeRadius: any) => {
+	let el = <HTMLElement>document.getElementById('3DEarth');
+	el.style.height = `${rightChartData5.value.offsetHeight}px`;
+	const myChart = echarts.init(el);
+	const option = {
+		globe: {
+			baseTexture: 'https://i.hd-r.cn/4d572a171eb475da0c2e731d15b63aea.jpg',
+			heightTexture: 'https://i.hd-r.cn/52356e8d906c84c5e23390f829dec7a3.jpg',
+			shading: 'realistic',
+			light: {
+				ambient: {
+					intensity: 0.4,
+				},
+				main: {
+					intensity: 0.4,
+				},
+			},
+			viewControl: {
+				autoRotate: true,
+			},
+			postEffect: {
+				enable: true,
+				bloom: {
+					enable: true,
+				},
+			},
+			globeRadius,
+		},
+		series: {
+			type: 'lines3D',
+			coordinateSystem: 'globe',
+			blendMode: 'lighter',
+			lineStyle: {
+				width: 1,
+				color: 'rgb(50, 50, 150)',
+				opacity: 0.1,
+			},
+			data: [],
+		},
+	};
+	// 随机模拟攻击线
+	let rodamData: any = function () {
+		let longitude = 105.18;
+		let longitude2 = Math.random() * 360 - 180;
+		let latitude = 37.51;
+		let latitude2 = Math.random() * 180 - 90;
+		return {
+			coords: [
+				[longitude2, latitude2],
+				[longitude, latitude],
+			],
+			value: (Math.random() * 3000).toFixed(2),
+		};
+	};
+	for (let i = 0; i < 150; i++) {
+		option.series.data = option.series.data.concat(rodamData());
+	}
+	myChart.setOption(option);
+};
+// 监听地球大小变化
+const initAddEventListener3DEarth = () => {
+	let w = document.body.clientWidth;
+	let globeRadius = 0;
+	if (w >= 1920) globeRadius = 100;
+	else if (w > 1200 && w < 1920) globeRadius = 70;
+	else if (w > 992 && w < 1200) globeRadius = 60;
+	else if (w > 768 && w < 992) globeRadius = 40;
+	else if (w < 768) globeRadius = 20;
+	init3DEarth(globeRadius);
+};
+// 批量设置 echarts resize
+const initEchartsResize = () => {
+	initAddEventListener3DEarth();
+	window.addEventListener('resize', () => {
+		for (let i = 0; i < state.myCharts.length; i++) {
+			state.myCharts[i].resize();
+		}
+		initAddEventListener3DEarth();
+	});
+};
+// 页面加载时
+onMounted(async () => {
+	NextLoading.done();
+	initTime();
+	await initRightChartData1();
+	await initRightChartData4();
+	await initRightChartData3();
+	await initRightChartData2();
+	await initRightChartData6();
+	await initEchartsResize();
+});
+// 页面卸载时
+onUnmounted(() => {
+	window.clearInterval(state.time.fun);
+});
+</script>
+
+<style scoped lang="scss">
+.visualizing-demo2 {
+	height: 100%;
+	width: 100%;
+	overflow: hidden;
+	background: url(https://i.hd-r.cn/b1040178e4a2265fe87ffbb9bda839a4.jpg);
+	background-size: 100% 100%;
+	display: flex;
+	flex-direction: column;
+	font-size: 13px;
+	.big-data-up {
+		height: 70px;
+		width: 100%;
+		display: flex;
+		align-items: center;
+		padding: 0 15px;
+		color: #43bdf0;
+		overflow: hidden;
+		.up-left {
+			width: 30%;
+			font-style: italic;
+		}
+		.up-center {
+			width: 40%;
+			display: flex;
+			justify-content: center;
+			font-size: 20px;
+			letter-spacing: 5px;
+			background-image: -webkit-linear-gradient(left, #43bdf0, #c0d1f2 25%, #43bdf0 50%, #c0d1f2 75%, #43bdf0);
+			-webkit-text-fill-color: transparent;
+			background-clip: text;
+			-webkit-background-clip: text;
+			background-size: 200% 100%;
+			animation: masked-animation 4s infinite linear;
+			-webkit-box-reflect: below -2px -webkit-gradient(linear, left top, left bottom, from(rgba(0, 0, 0, 0)), to(rgba(255, 255, 255, 0.1)));
+			@keyframes masked-animation {
+				0% {
+					background-position: 0 0;
+				}
+				100% {
+					background-position: -100% 0;
+				}
+			}
+			position: relative;
+			&::after {
+				content: '';
+				width: 50%;
+				position: absolute;
+				bottom: -15px;
+				left: 50%;
+				transform: translateX(-50%);
+				border: 1px transparent solid;
+				border-image: linear-gradient(to right, rgba(0, 0, 0, 0.1), #43bdf0) 1 10;
+			}
+			span {
+				cursor: pointer;
+			}
+		}
+		.up-right {
+			width: 30%;
+			justify-content: flex-end;
+			display: flex;
+			align-items: center;
+			.ml15:hover {
+				cursor: pointer;
+			}
+			:deep(.el-dropdown) {
+				font-size: 13px !important;
+				color: #43bdf0;
+				cursor: pointer;
+			}
+		}
+	}
+	.big-data-down {
+		flex: 1;
+		overflow: hidden;
+		display: flex;
+		.big-data-down-left,
+		.big-data-down-right {
+			width: 30%;
+			display: flex;
+			flex-direction: column;
+			.flex-warp-item {
+				padding: 0 7.5px 15px 15px;
+				width: 100%;
+				height: 33.33%;
+				.flex-warp-item-box {
+					width: 100%;
+					height: 100%;
+					background: rgba(22, 34, 58, 0.4);
+					display: flex;
+					flex-direction: column;
+					padding: 15px;
+					.flex-title {
+						margin-bottom: 15px;
+						color: #c0d1f2;
+						display: flex;
+						justify-content: space-between;
+						.flex-title-small {
+							font-size: 12px;
+						}
+					}
+					.flex-content {
+						flex: 1;
+						font-size: 12px;
+					}
+					.flex-content-overflow {
+						overflow: hidden;
+					}
+				}
+			}
+		}
+		.big-data-down-left {
+			color: #c0d1f2;
+			.sky {
+				display: flex;
+				align-items: center;
+				.sky-left {
+					font-size: 30px;
+				}
+				.sky-center {
+					flex: 1;
+					overflow: hidden;
+					padding: 0 10px;
+					.font {
+						margin-right: 15px;
+						background: unset !important;
+						border-radius: unset !important;
+						padding: unset !important;
+					}
+					span {
+						background: #22bc76;
+						border-radius: 2px;
+						padding: 0 5px;
+					}
+					.sky-tip {
+						overflow: hidden;
+						white-space: nowrap;
+						text-overflow: ellipsis;
+					}
+				}
+				.sky-right {
+					span {
+						font-size: 30px;
+					}
+					font {
+						font-size: 20px;
+					}
+				}
+			}
+			.sky-dd {
+				.sky-dl {
+					display: flex;
+					align-items: center;
+					height: 28px;
+					overflow: hidden;
+					div {
+						flex: 1;
+						overflow: hidden;
+						i {
+							font-size: 14px;
+						}
+					}
+					.tip {
+						overflow: hidden;
+						white-space: nowrap;
+						text-overflow: ellipsis;
+					}
+					&:hover {
+						background: rgba(0, 0, 0, 0.05);
+						cursor: default;
+						border-radius: 4px;
+					}
+					&:first-child:hover {
+						background: unset;
+					}
+				}
+				.sky-dl-first {
+					color: #43bdf0;
+				}
+			}
+			.d-states {
+				display: flex;
+				.d-states-item {
+					flex: 1;
+					display: flex;
+					align-items: center;
+					overflow: hidden;
+					i {
+						font-size: 20px;
+						height: 33px;
+						width: 33px;
+						line-height: 33px;
+						text-align: center;
+						border-radius: 100%;
+						flex-shrink: 1;
+						display: flex;
+						align-items: center;
+						justify-content: center;
+					}
+					.i-bg1 {
+						background: #22bc76;
+					}
+					.i-bg2 {
+						background: #e2356d;
+					}
+					.i-bg3 {
+						background: #43bbef;
+					}
+					.d-states-flex {
+						overflow: hidden;
+						padding: 0 10px 0;
+						.d-states-item-label {
+							color: #43bdf0;
+							overflow: hidden;
+							white-space: nowrap;
+							text-overflow: ellipsis;
+						}
+						.d-states-item-value {
+							font-size: 20px;
+							text-align: center;
+						}
+					}
+				}
+			}
+			.d-btn {
+				margin-top: 15px;
+				.d-btn-item {
+					border: 1px solid #c0d1f2;
+					display: flex;
+					width: 100%;
+					height: 35px;
+					border-radius: 35px;
+					align-items: center;
+					padding: 0 4px;
+					margin-top: 15px;
+					cursor: pointer;
+					transition: all ease 0.3s;
+					.d-btn-item-left {
+						font-size: 20px;
+						border: 1px solid #c0d1f2;
+						width: 25px;
+						height: 25px;
+						line-height: 25px;
+						border-radius: 100%;
+						text-align: center;
+						font-size: 14px;
+					}
+					.d-btn-item-center {
+						padding: 0 10px;
+						flex: 1;
+					}
+					.d-btn-item-eight {
+						text-align: right;
+						padding-right: 10px;
+					}
+				}
+				.d-btn-active {
+					transition: all ease 0.3s;
+					border: 1px solid #43bdf0;
+					color: #43bdf0;
+					.d-btn-item-left {
+						border: 1px solid #43bdf0;
+					}
+				}
+			}
+		}
+		.big-data-down-center {
+			width: 40%;
+			display: flex;
+			flex-direction: column;
+			.big-data-down-center-one {
+				height: 66.67%;
+				padding: 0 7.5px 15px;
+				.big-data-down-center-one-content {
+					height: 100%;
+					position: relative;
+					.fixed-top,
+					.fixed-right,
+					.fixed-bottom,
+					.fixed-left {
+						position: absolute;
+						width: 100px;
+						height: 100px;
+						display: flex;
+						cursor: pointer;
+						.circle {
+							position: absolute;
+							border-radius: 50%;
+							background: rgba(0, 0, 0, 0.01);
+							z-index: 10;
+						}
+						.text-box {
+							position: relative;
+							z-index: 11;
+							color: #c0d1f2;
+							margin: auto;
+							text-align: center;
+							font-size: 12px;
+							i {
+								font-size: 28px;
+								margin-bottom: 10px;
+							}
+						}
+					}
+					.fixed-top {
+						left: 20px;
+						top: 20px;
+					}
+					.fixed-right {
+						right: 20px;
+						top: 20px;
+					}
+					.fixed-bottom {
+						right: 20px;
+						bottom: 20px;
+					}
+					.fixed-left {
+						left: 20px;
+						bottom: 20px;
+					}
+					.circle:nth-of-type(1) {
+						width: 100px;
+						height: 95px;
+						animation: turnAround 6s infinite linear;
+						box-shadow: 0 0 1px 0 #869fe4, inset 0 0 10px 0 #869fe4;
+					}
+					.circle:nth-of-type(2) {
+						width: 95px;
+						height: 100px;
+						animation: turnAround 10s infinite linear;
+						box-shadow: 0 0 1px 0 #3397f2, inset 0 0 10px 0 #3397f2;
+					}
+					.circle:nth-of-type(3) {
+						width: 110px;
+						height: 100px;
+						animation: turnAround 5s infinite linear;
+						box-shadow: 0 0 1px 0 #3eaadc, inset 0 0 10px 0 #3eaadc;
+					}
+					.circle:nth-of-type(4) {
+						width: 100px;
+						height: 110px;
+						animation: turnAround 15s infinite linear;
+						box-shadow: 0 0 1px 0 #09f, inset 0 0 10px 0 #09f;
+					}
+					@keyframes turnAround {
+						100% {
+							transform: rotate(360deg);
+						}
+					}
+				}
+			}
+			.big-data-down-center-two {
+				padding: 0 7.5px 15px;
+				height: 33.33%;
+				.flex-warp-item-box {
+					width: 100%;
+					height: 100%;
+					background: rgba(22, 34, 58, 0.4);
+					display: flex;
+					flex-direction: column;
+					padding: 15px;
+					.flex-title {
+						margin-bottom: 15px;
+						color: #c0d1f2;
+						display: flex;
+						justify-content: space-between;
+						.flex-title-small {
+							font-size: 12px;
+						}
+					}
+					.flex-content {
+						flex: 1;
+						font-size: 12px;
+						display: flex;
+						height: calc(100% - 30px);
+						.flex-content-left {
+							display: flex;
+							flex-wrap: wrap;
+							width: 120px;
+							height: 100%;
+							.monitor-item {
+								width: 50%;
+								display: flex;
+								align-items: center;
+								.monitor-wave {
+									cursor: pointer;
+									width: 40px;
+									height: 40px;
+									position: relative;
+									background-color: #43bdf0;
+									border-radius: 50%;
+									overflow: hidden;
+									text-align: center;
+									&::before,
+									&::after {
+										content: '';
+										position: absolute;
+										left: 50%;
+										width: 40px;
+										height: 40px;
+										background: #f4f4f4;
+										animation: roateOne 10s linear infinite;
+										transform: translateX(-50%);
+										z-index: 1;
+									}
+									&::before {
+										bottom: 10px;
+										border-radius: 60%;
+									}
+									&::after {
+										bottom: 8px;
+										opacity: 0.7;
+										border-radius: 37%;
+									}
+									.monitor-z-index {
+										position: relative;
+										z-index: 2;
+										color: #4eb8ff;
+										display: flex;
+										align-items: center;
+										height: 100%;
+										justify-content: center;
+										font-weight: bold;
+									}
+								}
+								@keyframes roateOne {
+									0% {
+										transform: translate(-50%, 0) rotateZ(0deg);
+									}
+									50% {
+										transform: translate(-50%, -2%) rotateZ(180deg);
+									}
+									100% {
+										transform: translate(-50%, 0%) rotateZ(360deg);
+									}
+								}
+								.monitor-active {
+									background-color: #22bc76;
+									.monitor-z-index {
+										color: #22bc76;
+									}
+								}
+							}
+						}
+						.flex-content-right {
+							flex: 1;
+						}
+					}
+				}
+			}
+		}
+		.big-data-down-right {
+			.flex-warp-item {
+				padding: 0 15px 15px 7.5px;
+				.flex-content {
+					display: flex;
+					flex-direction: column;
+					.task {
+						display: flex;
+						height: 45px;
+						.task-item {
+							flex: 1;
+							color: #c0d1f2;
+							display: flex;
+							justify-content: center;
+							.task-item-box {
+								position: relative;
+								width: 45px;
+								height: 45px;
+								overflow: hidden;
+								border-radius: 100%;
+								z-index: 0;
+								display: flex;
+								align-items: center;
+								flex-direction: column;
+								justify-content: center;
+								box-shadow: 0 10px 12px 0 rgba(0, 0, 0, 0.3);
+								&::before {
+									content: '';
+									position: absolute;
+									z-index: -2;
+									left: -50%;
+									top: -50%;
+									width: 200%;
+									height: 200%;
+									background-repeat: no-repeat;
+									background-size: 50% 50%, 50% 50%;
+									background-position: 0 0, 100% 0, 100% 100%, 0 100%;
+									background-image: linear-gradient(#19d4ae, #19d4ae), linear-gradient(#5ab1ef, #5ab1ef), linear-gradient(#fa6e86, #fa6e86),
+										linear-gradient(#ffb980, #ffb980);
+									animation: rotate 2s linear infinite;
+								}
+								&::after {
+									content: '';
+									position: absolute;
+									z-index: -1;
+									left: 1px;
+									top: 1px;
+									width: calc(100% - 2px);
+									height: calc(100% - 2px);
+									border-radius: 100%;
+								}
+								.task-item-value {
+									text-align: center;
+									font-size: 14px;
+									font-weight: bold;
+								}
+								.task-item-label {
+									text-align: center;
+								}
+							}
+							.task1 {
+								&::after {
+									background: #5492be;
+								}
+							}
+							.task2 {
+								&::after {
+									background: #43a177;
+								}
+							}
+							.task3 {
+								&::after {
+									background: #a76077;
+								}
+							}
+							.task4 {
+								&::after {
+									background: #b4825a;
+								}
+							}
+							.task5 {
+								&::after {
+									background: #74568f;
+								}
+							}
+						}
+						.task-first-item {
+							flex-direction: column;
+							text-align: center;
+							.task-first {
+								font-size: 20px;
+							}
+						}
+					}
+				}
+			}
+			.progress {
+				flex: 1;
+			}
+		}
+	}
+}
+</style>

+ 51 - 0
src/views/visualizing/mock/demo1.ts

@@ -0,0 +1,51 @@
+// 地图模拟数据
+export const echartsMapList = [
+	{ name: '深圳市人民政府', value: '100' },
+	{ name: '莲花山公园', value: '100' },
+	{ name: '世界之窗', value: '100' },
+	{ name: '华侨城欢乐谷', value: '100' },
+	{ name: '宝安区西乡', value: '100' },
+];
+
+// 地图经纬度数据
+export const echartsMapData: object = {
+	深圳市人民政府: [114.064524, 22.549225],
+	莲花山公园: [114.0658, 22.560072],
+	世界之窗: [113.979419, 22.540579],
+	华侨城欢乐谷: [113.986066, 22.548056],
+	宝安区西乡: [113.869053, 22.581714],
+};
+
+// 地图图片显示
+export const echartsMapImgs = [
+	{
+		url: 'https://img1.baidu.com/it/u=2425496005,2401702709&fm=253&fmt=auto&app=120&f=JPEG?w=500&h=500',
+		name: '深圳市人民政府',
+		add: '深圳市福田区福中三路市民中心C区',
+		dec: '深圳市人民政府是根据《中华人民共和国地方各级人民代表大会和地方各级人民政府组织法》设立的,是深圳市人民代表大会的执行机关,是深圳市的国家行政机关。',
+	},
+	{
+		url: 'https://img0.baidu.com/it/u=2666213152,2487785512&fm=253&fmt=auto&app=120&f=JPEG?w=500&h=500',
+		name: '莲花山公园',
+		add: '广东省深圳市福田区莲花街道莲花北社区红荔路6030号',
+		dec: '莲花山公园筹建于1992年10月10日 ,1997年6月23日正式对外局部开放。',
+	},
+	{
+		url: 'https://img1.baidu.com/it/u=1595204841,1838139326&fm=253&fmt=auto&app=138&f=JPEG?w=500&h=500',
+		name: '世界之窗',
+		add: '深圳市南山区深南大道9037号',
+		dec: '这里,世界首座实景拍摄悬空式球幕影院“飞跃美利坚””,为游客提供集休闲放松于一体的都市时尚生活空间。',
+	},
+	{
+		url: 'https://img0.baidu.com/it/u=1586832283,2276617306&fm=253&fmt=auto&app=138&f=JPEG?w=476&h=500',
+		name: '华侨城欢乐谷',
+		add: '广东省深圳市南山区沙河街道星河街社区侨城西街1号',
+		dec: '深圳欢乐谷注重满足人们参与、体验的新型诱游需求,营造出自然、清新、活泼、惊奇、热烈、刺激的休闲旅游氛围。',
+	},
+	{
+		url: 'https://img0.baidu.com/it/u=2899429152,3158963267&fm=253&fmt=auto&app=138&f=JPEG?w=200&h=200',
+		name: '宝安区西乡',
+		add: '西乡街道下辖25个社区',
+		dec: '西乡街道,隶属于广东省深圳市宝安区,位于宝安区西南部,东接石岩街道,南接新安街道,西至珠江口岸边,北接航城街道。',
+	},
+];

+ 131 - 0
src/views/visualizing/mock/demo2.ts

@@ -0,0 +1,131 @@
+// 顶部下来菜单
+export const dropdownList: Array<object> = [
+	{
+		label: '广东省农业农村厅',
+	},
+	{
+		label: '广西省农业农村厅',
+	},
+	{
+		label: '四川省农业农村厅',
+	},
+	{
+		label: '湖北省农业农村厅',
+	},
+	{
+		label: '福建省农业农村厅',
+	},
+	{
+		label: '山东省农业农村厅',
+	},
+	{
+		label: '江西省农业农村厅',
+	},
+];
+
+// sky 天气
+export const skyList: Array<object> = [
+	{
+		v1: '时间',
+		v2: '天气',
+		v3: '温度',
+		v4: '湿度',
+		v5: '降水概率',
+		v6: '风向',
+		v7: '风力',
+		type: 'title',
+	},
+	{
+		v1: '今天',
+		v2: 'ele-Sunny',
+		v3: '20°/26°',
+		v4: '80%',
+		v5: '50%',
+		v6: '东南风',
+		v7: '13m/s',
+	},
+	{
+		v1: '明天',
+		v2: 'ele-Lightning',
+		v3: '20°/26°',
+		v4: '80%',
+		v5: '50%',
+		v6: '东南风',
+		v7: '13m/s',
+	},
+	{
+		v1: '后天',
+		v2: 'ele-Sunny',
+		v3: '20°/26°',
+		v4: '80%',
+		v5: '50%',
+		v6: '东南风',
+		v7: '13m/s',
+	},
+];
+
+// 当前设置状态
+export const dBtnList: Array<object> = [
+	{
+		v1: '地块A-灌溉',
+		v2: '阳光玫瑰种植',
+		v3: '126天',
+		v4: '设备在线',
+	},
+	{
+		v1: '地块B-收割',
+		v2: '阳光玫瑰种植',
+		v3: '360天',
+		v4: '设备预警',
+	},
+];
+
+// 当前设备监测
+export const chartData4List: Array<object> = [
+	{
+		label: '温度',
+	},
+	{
+		label: '光照',
+	},
+	{
+		label: '湿度',
+	},
+	{
+		label: '风力',
+	},
+	{
+		label: '张力',
+	},
+	{
+		label: '气压',
+	},
+];
+
+// 3DEarth 地图周围按钮组
+export const earth3DBtnList: Array<object> = [
+	{
+		topLevelClass: 'fixed-top',
+		icon: 'ele-MagicStick',
+		label: '环境监测',
+		type: 0,
+	},
+	{
+		topLevelClass: 'fixed-right',
+		icon: 'ele-MoonNight',
+		label: '精准管理',
+		type: 1,
+	},
+	{
+		topLevelClass: 'fixed-bottom',
+		icon: 'ele-TrendCharts',
+		label: '数据报表',
+		type: 2,
+	},
+	{
+		topLevelClass: 'fixed-left',
+		icon: 'ele-Van',
+		label: '产品追溯',
+		type: 3,
+	},
+];