feat:完善景区页面

This commit is contained in:
zjc
2024-12-18 17:40:16 +08:00
parent a2386b2789
commit 42c5ac6355
19 changed files with 783 additions and 71 deletions

286
package-lock.json generated
View File

@@ -18,6 +18,7 @@
"vue-countup-v3": "^1.4.2", "vue-countup-v3": "^1.4.2",
"vue-echarts": "^7.0.3", "vue-echarts": "^7.0.3",
"vue-router": "^4.4.5", "vue-router": "^4.4.5",
"vue-video-player": "^6.0.0",
"vue3-video-play": "^1.3.2" "vue3-video-play": "^1.3.2"
}, },
"devDependencies": { "devDependencies": {
@@ -425,6 +426,18 @@
"@babel/core": "^7.0.0-0" "@babel/core": "^7.0.0-0"
} }
}, },
"node_modules/@babel/runtime": {
"version": "7.26.0",
"resolved": "https://registry.npmmirror.com/@babel/runtime/-/runtime-7.26.0.tgz",
"integrity": "sha512-FDSOghenHTiToteC/QRlv2q3DhPZ/oOXTBoirfWNx1Cx3TMVcGWQtMMmQcSvb/JjpNeGzx8Pq/b4fKEJuWm1sw==",
"peer": true,
"dependencies": {
"regenerator-runtime": "^0.14.0"
},
"engines": {
"node": ">=6.9.0"
}
},
"node_modules/@babel/template": { "node_modules/@babel/template": {
"version": "7.25.9", "version": "7.25.9",
"resolved": "https://registry.npmmirror.com/@babel/template/-/template-7.25.9.tgz", "resolved": "https://registry.npmmirror.com/@babel/template/-/template-7.25.9.tgz",
@@ -816,11 +829,76 @@
"undici-types": "~6.20.0" "undici-types": "~6.20.0"
} }
}, },
"node_modules/@types/video.js": {
"version": "7.3.58",
"resolved": "https://registry.npmmirror.com/@types/video.js/-/video.js-7.3.58.tgz",
"integrity": "sha512-1CQjuSrgbv1/dhmcfQ83eVyYbvGyqhTvb2Opxr0QCV+iJ4J6/J+XWQ3Om59WiwCd1MN3rDUHasx5XRrpUtewYQ==",
"peer": true
},
"node_modules/@types/web-bluetooth": { "node_modules/@types/web-bluetooth": {
"version": "0.0.16", "version": "0.0.16",
"resolved": "https://registry.npmmirror.com/@types/web-bluetooth/-/web-bluetooth-0.0.16.tgz", "resolved": "https://registry.npmmirror.com/@types/web-bluetooth/-/web-bluetooth-0.0.16.tgz",
"integrity": "sha512-oh8q2Zc32S6gd/j50GowEjKLoOVOwHP/bWVjKJInBwQqdOYMdPrf1oVlelTlyfFK3CKxL1uahMDAr+vy8T7yMQ==" "integrity": "sha512-oh8q2Zc32S6gd/j50GowEjKLoOVOwHP/bWVjKJInBwQqdOYMdPrf1oVlelTlyfFK3CKxL1uahMDAr+vy8T7yMQ=="
}, },
"node_modules/@videojs-player/vue": {
"version": "1.0.0",
"resolved": "https://registry.npmmirror.com/@videojs-player/vue/-/vue-1.0.0.tgz",
"integrity": "sha512-WonTezRfKu3fYdQLt/ta+nuKH6gMZUv8l40Jke/j4Lae7IqeO/+lLAmBnh3ni88bwR+vkFXIlZ2Ci7VKInIYJg==",
"peerDependencies": {
"@types/video.js": "7.x",
"video.js": "7.x",
"vue": "3.x"
}
},
"node_modules/@videojs/http-streaming": {
"version": "2.16.3",
"resolved": "https://registry.npmmirror.com/@videojs/http-streaming/-/http-streaming-2.16.3.tgz",
"integrity": "sha512-91CJv5PnFBzNBvyEjt+9cPzTK/xoVixARj2g7ZAvItA+5bx8VKdk5RxCz/PP2kdzz9W+NiDUMPkdmTsosmy69Q==",
"peer": true,
"dependencies": {
"@babel/runtime": "^7.12.5",
"@videojs/vhs-utils": "3.0.5",
"aes-decrypter": "3.1.3",
"global": "^4.4.0",
"m3u8-parser": "4.8.0",
"mpd-parser": "^0.22.1",
"mux.js": "6.0.1",
"video.js": "^6 || ^7"
},
"engines": {
"node": ">=8",
"npm": ">=5"
},
"peerDependencies": {
"video.js": "^6 || ^7"
}
},
"node_modules/@videojs/vhs-utils": {
"version": "3.0.5",
"resolved": "https://registry.npmmirror.com/@videojs/vhs-utils/-/vhs-utils-3.0.5.tgz",
"integrity": "sha512-PKVgdo8/GReqdx512F+ombhS+Bzogiofy1LgAj4tN8PfdBx3HSS7V5WfJotKTqtOWGwVfSWsrYN/t09/DSryrw==",
"peer": true,
"dependencies": {
"@babel/runtime": "^7.12.5",
"global": "^4.4.0",
"url-toolkit": "^2.2.1"
},
"engines": {
"node": ">=8",
"npm": ">=5"
}
},
"node_modules/@videojs/xhr": {
"version": "2.6.0",
"resolved": "https://registry.npmmirror.com/@videojs/xhr/-/xhr-2.6.0.tgz",
"integrity": "sha512-7J361GiN1tXpm+gd0xz2QWr3xNWBE+rytvo8J3KuggFaLg+U37gZQ2BuPLcnkfGffy2e+ozY70RHC8jt7zjA6Q==",
"peer": true,
"dependencies": {
"@babel/runtime": "^7.5.5",
"global": "~4.4.0",
"is-function": "^1.0.1"
}
},
"node_modules/@vitejs/plugin-vue": { "node_modules/@vitejs/plugin-vue": {
"version": "5.2.1", "version": "5.2.1",
"resolved": "https://registry.npmmirror.com/@vitejs/plugin-vue/-/plugin-vue-5.2.1.tgz", "resolved": "https://registry.npmmirror.com/@vitejs/plugin-vue/-/plugin-vue-5.2.1.tgz",
@@ -1249,6 +1327,15 @@
"@xtuc/long": "4.2.2" "@xtuc/long": "4.2.2"
} }
}, },
"node_modules/@xmldom/xmldom": {
"version": "0.8.10",
"resolved": "https://registry.npmmirror.com/@xmldom/xmldom/-/xmldom-0.8.10.tgz",
"integrity": "sha512-2WALfTl4xo2SkGCYRt6rDTFfk9R1czmBvUQy12gK2KuRKIpWEhcbbzy8EZXtz/jkRqHX8bFEc6FC1HjX4TUWYw==",
"peer": true,
"engines": {
"node": ">=10.0.0"
}
},
"node_modules/@xtuc/ieee754": { "node_modules/@xtuc/ieee754": {
"version": "1.2.0", "version": "1.2.0",
"resolved": "https://registry.npmmirror.com/@xtuc/ieee754/-/ieee754-1.2.0.tgz", "resolved": "https://registry.npmmirror.com/@xtuc/ieee754/-/ieee754-1.2.0.tgz",
@@ -1275,6 +1362,18 @@
"node": ">=0.4.0" "node": ">=0.4.0"
} }
}, },
"node_modules/aes-decrypter": {
"version": "3.1.3",
"resolved": "https://registry.npmmirror.com/aes-decrypter/-/aes-decrypter-3.1.3.tgz",
"integrity": "sha512-VkG9g4BbhMBy+N5/XodDeV6F02chEk9IpgRTq/0bS80y4dzy79VH2Gtms02VXomf3HmyRe3yyJYkJ990ns+d6A==",
"peer": true,
"dependencies": {
"@babel/runtime": "^7.12.5",
"@videojs/vhs-utils": "^3.0.5",
"global": "^4.4.0",
"pkcs7": "^1.0.4"
}
},
"node_modules/ajv": { "node_modules/ajv": {
"version": "6.12.6", "version": "6.12.6",
"resolved": "https://registry.npmmirror.com/ajv/-/ajv-6.12.6.tgz", "resolved": "https://registry.npmmirror.com/ajv/-/ajv-6.12.6.tgz",
@@ -1673,6 +1772,12 @@
"node": ">=0.10" "node": ">=0.10"
} }
}, },
"node_modules/dom-walk": {
"version": "0.1.2",
"resolved": "https://registry.npmmirror.com/dom-walk/-/dom-walk-0.1.2.tgz",
"integrity": "sha512-6QvTW9mrGeIegrFXdtQi9pk7O/nSK6lSdXW2eqUspN5LWD7UTji2Fqw5V2YLjBpHEoU9Xl/eUWNpDeZvoyOv2w==",
"peer": true
},
"node_modules/echarts": { "node_modules/echarts": {
"version": "5.5.1", "version": "5.5.1",
"resolved": "https://registry.npmmirror.com/echarts/-/echarts-5.5.1.tgz", "resolved": "https://registry.npmmirror.com/echarts/-/echarts-5.5.1.tgz",
@@ -2100,6 +2205,16 @@
"dev": true, "dev": true,
"peer": true "peer": true
}, },
"node_modules/global": {
"version": "4.4.0",
"resolved": "https://registry.npmmirror.com/global/-/global-4.4.0.tgz",
"integrity": "sha512-wv/LAoHdRE3BeTGz53FAamhGlPLhlssK45usmGFThIi4XqnBmjKQ16u+RNbP7WvigRZDxUsM0J3gcQ5yicaL0w==",
"peer": true,
"dependencies": {
"min-document": "^2.19.0",
"process": "^0.11.10"
}
},
"node_modules/globals": { "node_modules/globals": {
"version": "11.12.0", "version": "11.12.0",
"resolved": "https://registry.npmmirror.com/globals/-/globals-11.12.0.tgz", "resolved": "https://registry.npmmirror.com/globals/-/globals-11.12.0.tgz",
@@ -2164,6 +2279,12 @@
"integrity": "sha512-P8IdPQHq3lA1xVeBRi5VPqUm5HDgKnx0Ru51wZz5mjxHr5n3RWhjIpOFU7ybkUxfB+5IToy+OLaHYDBIWsv+uw==", "integrity": "sha512-P8IdPQHq3lA1xVeBRi5VPqUm5HDgKnx0Ru51wZz5mjxHr5n3RWhjIpOFU7ybkUxfB+5IToy+OLaHYDBIWsv+uw==",
"dev": true "dev": true
}, },
"node_modules/individual": {
"version": "2.0.0",
"resolved": "https://registry.npmmirror.com/individual/-/individual-2.0.0.tgz",
"integrity": "sha512-pWt8hBCqJsUWI/HtcfWod7+N9SgAqyPEaF7JQjwzjn5vGrpg6aQ5qeAFQ7dx//UH4J1O+7xqew+gCeeFt6xN/g==",
"peer": true
},
"node_modules/is-binary-path": { "node_modules/is-binary-path": {
"version": "2.1.0", "version": "2.1.0",
"resolved": "https://registry.npmmirror.com/is-binary-path/-/is-binary-path-2.1.0.tgz", "resolved": "https://registry.npmmirror.com/is-binary-path/-/is-binary-path-2.1.0.tgz",
@@ -2200,6 +2321,12 @@
"node": ">=0.10.0" "node": ">=0.10.0"
} }
}, },
"node_modules/is-function": {
"version": "1.0.2",
"resolved": "https://registry.npmmirror.com/is-function/-/is-function-1.0.2.tgz",
"integrity": "sha512-lw7DUp0aWXYg+CBCN+JKkcE0Q2RayZnSvnZBlwgxHBQhqt5pZNVy4Ri7H9GmmXkdu7LUthszM+Tor1u/2iBcpQ==",
"peer": true
},
"node_modules/is-glob": { "node_modules/is-glob": {
"version": "4.0.3", "version": "4.0.3",
"resolved": "https://registry.npmmirror.com/is-glob/-/is-glob-4.0.3.tgz", "resolved": "https://registry.npmmirror.com/is-glob/-/is-glob-4.0.3.tgz",
@@ -2399,6 +2526,12 @@
"graceful-fs": "^4.1.6" "graceful-fs": "^4.1.6"
} }
}, },
"node_modules/keycode": {
"version": "2.2.1",
"resolved": "https://registry.npmmirror.com/keycode/-/keycode-2.2.1.tgz",
"integrity": "sha512-Rdgz9Hl9Iv4QKi8b0OlCRQEzp4AgVxyCtz5S/+VIHezDmrDhkp2N2TqBWOLz0/gbeREXOOiI9/4b8BY9uw2vFg==",
"peer": true
},
"node_modules/kind-of": { "node_modules/kind-of": {
"version": "6.0.3", "version": "6.0.3",
"resolved": "https://registry.npmmirror.com/kind-of/-/kind-of-6.0.3.tgz", "resolved": "https://registry.npmmirror.com/kind-of/-/kind-of-6.0.3.tgz",
@@ -2495,6 +2628,17 @@
"yallist": "^3.0.2" "yallist": "^3.0.2"
} }
}, },
"node_modules/m3u8-parser": {
"version": "4.8.0",
"resolved": "https://registry.npmmirror.com/m3u8-parser/-/m3u8-parser-4.8.0.tgz",
"integrity": "sha512-UqA2a/Pw3liR6Df3gwxrqghCP17OpPlQj6RBPLYygf/ZSQ4MoSgvdvhvt35qV+3NaaA0FSZx93Ix+2brT1U7cA==",
"peer": true,
"dependencies": {
"@babel/runtime": "^7.12.5",
"@videojs/vhs-utils": "^3.0.5",
"global": "^4.4.0"
}
},
"node_modules/magic-string": { "node_modules/magic-string": {
"version": "0.30.14", "version": "0.30.14",
"resolved": "https://registry.npmmirror.com/magic-string/-/magic-string-0.30.14.tgz", "resolved": "https://registry.npmmirror.com/magic-string/-/magic-string-0.30.14.tgz",
@@ -2568,6 +2712,15 @@
"node": ">= 0.6" "node": ">= 0.6"
} }
}, },
"node_modules/min-document": {
"version": "2.19.0",
"resolved": "https://registry.npmmirror.com/min-document/-/min-document-2.19.0.tgz",
"integrity": "sha512-9Wy1B3m3f66bPPmU5hdA4DR4PB2OfDU/+GS3yAB7IQozE3tqXaVv2zOjgla7MEGSRv95+ILmOuvhLkOK6wJtCQ==",
"peer": true,
"dependencies": {
"dom-walk": "^0.1.0"
}
},
"node_modules/minimatch": { "node_modules/minimatch": {
"version": "9.0.5", "version": "9.0.5",
"resolved": "https://registry.npmmirror.com/minimatch/-/minimatch-9.0.5.tgz", "resolved": "https://registry.npmmirror.com/minimatch/-/minimatch-9.0.5.tgz",
@@ -2610,6 +2763,21 @@
"ufo": "^1.5.4" "ufo": "^1.5.4"
} }
}, },
"node_modules/mpd-parser": {
"version": "0.22.1",
"resolved": "https://registry.npmmirror.com/mpd-parser/-/mpd-parser-0.22.1.tgz",
"integrity": "sha512-fwBebvpyPUU8bOzvhX0VQZgSohncbgYwUyJJoTSNpmy7ccD2ryiCvM7oRkn/xQH5cv73/xU7rJSNCLjdGFor0Q==",
"peer": true,
"dependencies": {
"@babel/runtime": "^7.12.5",
"@videojs/vhs-utils": "^3.0.5",
"@xmldom/xmldom": "^0.8.3",
"global": "^4.4.0"
},
"bin": {
"mpd-to-m3u8-json": "bin/parse.js"
}
},
"node_modules/mrmime": { "node_modules/mrmime": {
"version": "2.0.0", "version": "2.0.0",
"resolved": "https://registry.npmmirror.com/mrmime/-/mrmime-2.0.0.tgz", "resolved": "https://registry.npmmirror.com/mrmime/-/mrmime-2.0.0.tgz",
@@ -2625,6 +2793,23 @@
"integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
"dev": true "dev": true
}, },
"node_modules/mux.js": {
"version": "6.0.1",
"resolved": "https://registry.npmmirror.com/mux.js/-/mux.js-6.0.1.tgz",
"integrity": "sha512-22CHb59rH8pWGcPGW5Og7JngJ9s+z4XuSlYvnxhLuc58cA1WqGDQPzuG8I+sPm1/p0CdgpzVTaKW408k5DNn8w==",
"peer": true,
"dependencies": {
"@babel/runtime": "^7.11.2",
"global": "^4.4.0"
},
"bin": {
"muxjs-transmux": "bin/transmux.js"
},
"engines": {
"node": ">=8",
"npm": ">=5"
}
},
"node_modules/nanoid": { "node_modules/nanoid": {
"version": "3.3.8", "version": "3.3.8",
"resolved": "https://registry.npmmirror.com/nanoid/-/nanoid-3.3.8.tgz", "resolved": "https://registry.npmmirror.com/nanoid/-/nanoid-3.3.8.tgz",
@@ -2821,6 +3006,18 @@
} }
} }
}, },
"node_modules/pkcs7": {
"version": "1.0.4",
"resolved": "https://registry.npmmirror.com/pkcs7/-/pkcs7-1.0.4.tgz",
"integrity": "sha512-afRERtHn54AlwaF2/+LFszyAANTCggGilmcmILUzEjvs3XgFZT+xE6+QWQcAGmu4xajy+Xtj7acLOPdx5/eXWQ==",
"peer": true,
"dependencies": {
"@babel/runtime": "^7.5.5"
},
"bin": {
"pkcs7": "bin/cli.js"
}
},
"node_modules/pkg-types": { "node_modules/pkg-types": {
"version": "1.2.1", "version": "1.2.1",
"resolved": "https://registry.npmmirror.com/pkg-types/-/pkg-types-1.2.1.tgz", "resolved": "https://registry.npmmirror.com/pkg-types/-/pkg-types-1.2.1.tgz",
@@ -2874,6 +3071,15 @@
"url": "https://github.com/sponsors/sindresorhus" "url": "https://github.com/sponsors/sindresorhus"
} }
}, },
"node_modules/process": {
"version": "0.11.10",
"resolved": "https://registry.npmmirror.com/process/-/process-0.11.10.tgz",
"integrity": "sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A==",
"peer": true,
"engines": {
"node": ">= 0.6.0"
}
},
"node_modules/proxy-from-env": { "node_modules/proxy-from-env": {
"version": "1.1.0", "version": "1.1.0",
"resolved": "https://registry.npmmirror.com/proxy-from-env/-/proxy-from-env-1.1.0.tgz", "resolved": "https://registry.npmmirror.com/proxy-from-env/-/proxy-from-env-1.1.0.tgz",
@@ -2931,6 +3137,12 @@
"url": "https://paulmillr.com/funding/" "url": "https://paulmillr.com/funding/"
} }
}, },
"node_modules/regenerator-runtime": {
"version": "0.14.1",
"resolved": "https://registry.npmmirror.com/regenerator-runtime/-/regenerator-runtime-0.14.1.tgz",
"integrity": "sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==",
"peer": true
},
"node_modules/reusify": { "node_modules/reusify": {
"version": "1.0.4", "version": "1.0.4",
"resolved": "https://registry.npmmirror.com/reusify/-/reusify-1.0.4.tgz", "resolved": "https://registry.npmmirror.com/reusify/-/reusify-1.0.4.tgz",
@@ -3019,6 +3231,15 @@
"queue-microtask": "^1.2.2" "queue-microtask": "^1.2.2"
} }
}, },
"node_modules/rust-result": {
"version": "1.0.0",
"resolved": "https://registry.npmmirror.com/rust-result/-/rust-result-1.0.0.tgz",
"integrity": "sha512-6cJzSBU+J/RJCF063onnQf0cDUOHs9uZI1oroSGnHOph+CQTIJ5Pp2hK5kEQq1+7yE/EEWfulSNXAQ2jikPthA==",
"peer": true,
"dependencies": {
"individual": "^2.0.0"
}
},
"node_modules/safe-buffer": { "node_modules/safe-buffer": {
"version": "5.2.1", "version": "5.2.1",
"resolved": "https://registry.npmmirror.com/safe-buffer/-/safe-buffer-5.2.1.tgz", "resolved": "https://registry.npmmirror.com/safe-buffer/-/safe-buffer-5.2.1.tgz",
@@ -3040,6 +3261,15 @@
], ],
"peer": true "peer": true
}, },
"node_modules/safe-json-parse": {
"version": "4.0.0",
"resolved": "https://registry.npmmirror.com/safe-json-parse/-/safe-json-parse-4.0.0.tgz",
"integrity": "sha512-RjZPPHugjK0TOzFrLZ8inw44s9bKox99/0AZW9o/BEQVrJfhI+fIHMErnPyRa89/yRXUUr93q+tiN6zhoVV4wQ==",
"peer": true,
"dependencies": {
"rust-result": "^1.0.0"
}
},
"node_modules/sass": { "node_modules/sass": {
"version": "1.82.0", "version": "1.82.0",
"resolved": "https://registry.npmmirror.com/sass/-/sass-1.82.0.tgz", "resolved": "https://registry.npmmirror.com/sass/-/sass-1.82.0.tgz",
@@ -3668,6 +3898,48 @@
"punycode": "^2.1.0" "punycode": "^2.1.0"
} }
}, },
"node_modules/url-toolkit": {
"version": "2.2.5",
"resolved": "https://registry.npmmirror.com/url-toolkit/-/url-toolkit-2.2.5.tgz",
"integrity": "sha512-mtN6xk+Nac+oyJ/PrI7tzfmomRVNFIWKUbG8jdYFt52hxbiReFAXIjYskvu64/dvuW71IcB7lV8l0HvZMac6Jg==",
"peer": true
},
"node_modules/video.js": {
"version": "7.21.6",
"resolved": "https://registry.npmmirror.com/video.js/-/video.js-7.21.6.tgz",
"integrity": "sha512-m41TbODrUCToVfK1aljVd296CwDQnCRewpIm5tTXMuV87YYSGw1H+VDOaV45HlpcWSsTWWLF++InDgGJfthfUw==",
"peer": true,
"dependencies": {
"@babel/runtime": "^7.12.5",
"@videojs/http-streaming": "2.16.3",
"@videojs/vhs-utils": "^3.0.4",
"@videojs/xhr": "2.6.0",
"aes-decrypter": "3.1.3",
"global": "^4.4.0",
"keycode": "^2.2.0",
"m3u8-parser": "4.8.0",
"mpd-parser": "0.22.1",
"mux.js": "6.0.1",
"safe-json-parse": "4.0.0",
"videojs-font": "3.2.0",
"videojs-vtt.js": "^0.15.5"
}
},
"node_modules/videojs-font": {
"version": "3.2.0",
"resolved": "https://registry.npmmirror.com/videojs-font/-/videojs-font-3.2.0.tgz",
"integrity": "sha512-g8vHMKK2/JGorSfqAZQUmYYNnXmfec4MLhwtEFS+mMs2IDY398GLysy6BH6K+aS1KMNu/xWZ8Sue/X/mdQPliA==",
"peer": true
},
"node_modules/videojs-vtt.js": {
"version": "0.15.5",
"resolved": "https://registry.npmmirror.com/videojs-vtt.js/-/videojs-vtt.js-0.15.5.tgz",
"integrity": "sha512-yZbBxvA7QMYn15Lr/ZfhhLPrNpI/RmCSCqgIff57GC2gIrV5YfyzLfLyZMj0NnZSAz8syB4N0nHXpZg9MyrMOQ==",
"peer": true,
"dependencies": {
"global": "^4.3.1"
}
},
"node_modules/vite": { "node_modules/vite": {
"version": "6.0.2", "version": "6.0.2",
"resolved": "https://registry.npmmirror.com/vite/-/vite-6.0.2.tgz", "resolved": "https://registry.npmmirror.com/vite/-/vite-6.0.2.tgz",
@@ -3912,11 +4184,23 @@
"vue": "^3.2.0" "vue": "^3.2.0"
} }
}, },
"node_modules/vue-video-player": {
"version": "6.0.0",
"resolved": "https://registry.npmmirror.com/vue-video-player/-/vue-video-player-6.0.0.tgz",
"integrity": "sha512-WP47OtefsjMEReRCIKIL3tRRgH/PyNm8ELjsbYgr/WWrYAj5Ih9Adzkzp+ylYOI/v57jJ4O7O4XkbXBCmsTqNw==",
"dependencies": {
"@videojs-player/vue": "1.x"
},
"peerDependencies": {
"@types/video.js": "7.x",
"video.js": "7.x",
"vue": "3.x"
}
},
"node_modules/vue3-video-play": { "node_modules/vue3-video-play": {
"version": "1.3.2", "version": "1.3.2",
"resolved": "https://registry.npmmirror.com/vue3-video-play/-/vue3-video-play-1.3.2.tgz", "resolved": "https://registry.npmmirror.com/vue3-video-play/-/vue3-video-play-1.3.2.tgz",
"integrity": "sha512-eEwCJ0NIkfVQgTj0I3Kf9b1E/04Qne8mQQiE8r77BocblHsZ2T6af3q8l8Zzs/OvjlpQAQvkN/ACVUOJC3RSXg==", "integrity": "sha512-eEwCJ0NIkfVQgTj0I3Kf9b1E/04Qne8mQQiE8r77BocblHsZ2T6af3q8l8Zzs/OvjlpQAQvkN/ACVUOJC3RSXg==",
"license": "ISC",
"dependencies": { "dependencies": {
"hls.js": "^1.0.10", "hls.js": "^1.0.10",
"throttle-debounce": "^3.0.1", "throttle-debounce": "^3.0.1",

View File

@@ -19,6 +19,7 @@
"vue-countup-v3": "^1.4.2", "vue-countup-v3": "^1.4.2",
"vue-echarts": "^7.0.3", "vue-echarts": "^7.0.3",
"vue-router": "^4.4.5", "vue-router": "^4.4.5",
"vue-video-player": "^6.0.0",
"vue3-video-play": "^1.3.2" "vue3-video-play": "^1.3.2"
}, },
"devDependencies": { "devDependencies": {

Binary file not shown.

Before

Width:  |  Height:  |  Size: 22 KiB

BIN
src/assets/images/car.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

BIN
src/assets/images/close.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 688 B

BIN
src/assets/images/full.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 31 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 28 KiB

BIN
src/assets/images/ship.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

View File

@@ -5,7 +5,7 @@
<span class="label">{{ label }}</span> <span class="label">{{ label }}</span>
</div> </div>
<div class="count"> <div class="count">
<img class="bg" src="@/assets/images/count-bg.svg" /> <img class="bg" src="@/assets/images/mask-success.png" />
<div class="flex align-center"> <div class="flex align-center">
<countup class="value" :end-val="count" /> <countup class="value" :end-val="count" />
<span class="suffix">{{ suffix }}</span> <span class="suffix">{{ suffix }}</span>
@@ -16,6 +16,7 @@
<script setup> <script setup>
import countup from 'vue-countup-v3' import countup from 'vue-countup-v3'
let props = defineProps({ let props = defineProps({
label: { label: {
type: String, type: String,
@@ -25,6 +26,10 @@
type: Number, type: Number,
default: 0 default: 0
}, },
mode: {
type: Number,
default: 0
},
suffix: { suffix: {
type: String, type: String,
default: '' default: ''

View File

@@ -0,0 +1,124 @@
<template>
<div
:id="id"
:style="{
width: styleUtil.px2vw(width),
height: styleUtil.px2vh(height)
}"
/>
</template>
<script setup>
import * as echarts from 'echarts'
import styleUtil from '@/utils/styleUtil'
import { fitChartSize } from '@/utils/dataUtil'
import { guid } from '@/utils/util'
const props = defineProps({
width: {
type: Number,
default: () => 0
},
height: {
type: Number,
default: () => 0
},
config: {
type: Object,
default: () => {
return {}
}
}
})
let id = ref(guid())
let pieChart = null
var colorList = ['#FDC40A', '#FF5232', '#50F0A6', '#5FDFFA', '']
var title = ['企业', '农业', '工业', '纺织']
var dataValue = ['15', '30', '35', '20']
var dataList = title.map((item, index) => {
return {
name: item,
value: dataValue[index]
}
})
var defaultCofig = {
color: colorList,
legend: {
orient: 'horizontal',
bottom: '10%',
left: '4%',
data: dataList,
itemWidth: fitChartSize(16),
itemHeight: fitChartSize(16),
itemGap: fitChartSize(10),
formatter: (name) => {
return name + '\u3000' + '19%'
},
textStyle: {
color: '#ffffff',
fontSize: fitChartSize(12)
}
},
series: [
{
type: 'pie',
center: ['50%', '40%'],
radius: ['55%', '70%'],
itemStyle: {
borderWidth: fitChartSize(4),
borderColor: '#093672'
},
label: {
show: true,
position: 'center',
fontWeight: 'bold',
formatter: function (o) {
return `{value|123456}` + '\n' + `{name|整改率}`
},
rich: {
value: {
color: '#fff',
fontSize: fitChartSize(24),
fontWeight: 'bold',
padding: [0, 0, 5, 0]
},
name: {
color: '#7894A8',
fontSize: fitChartSize(12)
}
}
},
labelLine: {
show: false
},
data: dataList
}
]
}
const resize = () => {
if (pieChart) {
pieChart.dispose()
pieChart = null
init()
}
}
const init = () => {
const dom = document.getElementById(id.value)
pieChart = echarts.init(dom)
pieChart.setOption({
...defaultCofig,
...props.config
})
// 监听窗口大小变化
window.addEventListener('resize', resize)
}
onMounted(() => {
init()
})
</script>
<style scoped lang="scss"></style>

View File

@@ -13,6 +13,7 @@
import styleUtil from '@/utils/styleUtil' import styleUtil from '@/utils/styleUtil'
import { fitChartSize } from '@/utils/dataUtil' import { fitChartSize } from '@/utils/dataUtil'
import { guid } from '@/utils/util' import { guid } from '@/utils/util'
const props = defineProps({ const props = defineProps({
width: { width: {
type: Number, type: Number,
@@ -21,6 +22,12 @@
height: { height: {
type: Number, type: Number,
default: () => 0 default: () => 0
},
config: {
type: Object,
default: () => {
return {}
}
} }
}) })
@@ -38,56 +45,54 @@
var defaultCofig = { var defaultCofig = {
color: colorList, color: colorList,
title: { legend: {
show: true, orient: 'vertical',
text: '100%', bottom: 'center',
itemGap: 10, left: '70%',
x: 'center', data: dataList,
y: '30%', itemWidth: fitChartSize(16),
subtext: '脱岗率', itemHeight: fitChartSize(16),
textStyle: { itemGap: fitChartSize(10),
fontSize: fitChartSize(24), formatter: (name) => {
fontWeight: 'bold', return name + '\u3000' + '19%'
color: '#ffffff'
}, },
subtextStyle: { textStyle: {
fontSize: fitChartSize(12), color: '#ffffff',
fontWeight: 'bold', fontSize: fitChartSize(12)
color: '#7894A8'
} }
}, },
legend: {
top: 'bottom',
left: 'center',
orient: 'horizontal',
data: dataList,
itemWidth: 16,
itemHeight: 16,
itemGap: 10
},
series: [ series: [
//
{ {
type: 'pie', type: 'pie',
center: ['50%', '30%'], center: ['30%', '50%'],
radius: ['40%', '55%'], radius: ['40%', '55%'],
itemStyle: { itemStyle: {
borderWidth: fitChartSize(2), //线 borderWidth: fitChartSize(4),
borderColor: '#093672' borderColor: '#093672'
}, },
label: { label: {
show: false show: true,
position: 'center',
fontWeight: 'bold',
formatter: function (o) {
return `{value|123456}` + '\n' + `{name|整改率}`
},
rich: {
value: {
color: '#fff',
fontSize: fitChartSize(24),
fontWeight: 'bold',
padding: [0, 0, 5, 0]
},
name: {
color: '#7894A8',
fontSize: fitChartSize(12)
}
}
}, },
labelLine: { labelLine: {
show: true, show: false
normal: {
length: 20,
length2: 40,
align: 'center',
lineStyle: {
width: 1
}
}
}, },
data: dataList data: dataList
} }
@@ -105,7 +110,8 @@
const dom = document.getElementById(id.value) const dom = document.getElementById(id.value)
pieChart = echarts.init(dom) pieChart = echarts.init(dom)
pieChart.setOption({ pieChart.setOption({
...defaultCofig ...defaultCofig,
...props.config
}) })
// //
window.addEventListener('resize', resize) window.addEventListener('resize', resize)

30
src/hooks/map.js Normal file
View File

@@ -0,0 +1,30 @@
import { ref } from 'vue'
export function useMap() {
let map = ref(null)
// 初始化地图
const initMap = (id, lat, lng, scale = 15) => {
map.value = new BMapGL.Map(id)
map.value.centerAndZoom(new BMapGL.Point(lat, lng), scale)
map.value.enableScrollWheelZoom(true)
}
// 添加图标
const addMarker = (icon, position = [0, 0], size = [20, 20], offset = [0, 0]) => {
var iconPath = new BMapGL.Icon(icon, new BMapGL.Size(...size), {
// 指定定位位置。
// 当标注显示在地图上时,其所指向的地理位置距离图标左上
// 角各偏移10像素和25像素。您可以看到在本例中该位置即是
// 图标中央下端的尖角位置。
// 设置图片偏移。
// 当您需要从一幅较大的图片中截取某部分作为标注图标时,您
// 需要指定大图的偏移位置此做法与css sprites技术类似。
// imageOffset: new BMapGL.Size(...offset) // 设置图片偏移
})
var point = new BMapGL.Point(...position)
// 创建标注对象并添加到地图
var marker = new BMapGL.Marker(point, { icon: iconPath })
map.value.addOverlay(marker)
}
return { map, initMap, addMarker }
}

View File

@@ -4,11 +4,11 @@ import App from './App.vue'
import router from './router' import router from './router'
import '@/styles/reset.css' import '@/styles/reset.css'
import '@/styles/common.scss' import '@/styles/common.scss'
import vue3videoPlay from 'vue3-video-play' // 引入组件 // import vue3videoPlay from 'vue3-video-play' // 引入组件
import 'vue3-video-play/dist/style.css' // 引入css // import 'vue3-video-play/dist/style.css' // 引入css
const app = createApp(App) const app = createApp(App)
app.use(vue3videoPlay) // app.use(vue3videoPlay)
app.use(createPinia()) app.use(createPinia())
app.use(router) app.use(router)

View File

@@ -1,5 +1,4 @@
import { createRouter, createWebHistory } from 'vue-router' import { createRouter, createWebHistory } from 'vue-router'
const router = createRouter({ const router = createRouter({
history: createWebHistory(import.meta.env.BASE_URL), history: createWebHistory(import.meta.env.BASE_URL),
routes: [ routes: [

View File

@@ -20,22 +20,22 @@
justify-content: space-evenly; justify-content: space-evenly;
} }
.mb-6 { .mb-6 {
margin-bottom: vh(6); margin-bottom: vh(6) !important;
} }
.pt-10 { .pt-10 {
padding-top: vh(10); padding-top: vh(10) !important;
} }
.pb-10 { .pb-10 {
padding-bottom: vh(10); padding-bottom: vh(10) !important;
} }
.mb-10 { .mb-10 {
margin-bottom: vh(10); margin-bottom: vh(10) !important;
} }
.mt-10 { .mt-10 {
margin-top: vh(10) !important; margin-top: vh(10) !important;
} }
.mr-10 { .mr-10 {
margin-right: vh(10); margin-right: vh(10) !important;
} }
.mt-20 { .mt-20 {
margin-top: vh(20) !important; margin-top: vh(20) !important;
@@ -44,8 +44,8 @@
margin-left: vh(20) !important; margin-left: vh(20) !important;
} }
.pt-20 { .pt-20 {
padding-top: vh(20); padding-top: vh(20) !important;
} }
.pt-20 { .pr-20 {
padding-top: vh(20); padding-right: vh(20) !important;
} }

View File

@@ -0,0 +1,63 @@
<template>
<div class="dialog">
<el-dialog v-model="modelValue" align-center :modal="false" :show-close="false">
<div id="big-car-ship" class="big-car-ship" />
<img class="close" src="@/assets/images/close.png" @click="modelValue = false" />
</el-dialog>
</div>
</template>
<script setup>
import carIcon from '@/assets/images/car.png'
import shipIcon from '@/assets/images/ship.png'
import { useMap } from '@/hooks/map'
let modelValue = defineModel()
const { map, initMap, addMarker } = useMap()
watch(
() => modelValue.value,
(val) => {
if (val && !map.value) {
setTimeout(() => {
initMap('big-car-ship', 109.491961, 31.024285, 16)
addMarker(carIcon, [109.491045, 31.028725], [36, 50])
addMarker(carIcon, [109.483266, 31.024718], [36, 50])
addMarker(shipIcon, [109.479062, 31.021499], [36, 50])
addMarker(shipIcon, [109.488907, 31.017476], [36, 50])
}, 500)
}
}
)
</script>
<style scoped lang="scss">
:deep(.BMap_cpyCtrl) {
display: none;
}
:deep(.anchorBL) {
display: none;
}
.dialog {
:deep(.el-dialog) {
width: vw(2540);
height: vh(900);
padding: 0;
}
:deep(.el-dialog__header) {
padding-bottom: 0 !important;
}
}
.big-car-ship {
width: vw(2540);
height: vh(900);
}
.close {
cursor: pointer;
position: absolute;
right: vw(20);
top: vh(20);
width: vw(60);
z-index: 9999;
}
</style>

View File

@@ -19,7 +19,7 @@
<div class="box mr-10"> <div class="box mr-10">
<Title1 title="景区承载" /> <Title1 title="景区承载" />
<div class="flex"> <div class="flex">
<FProgress :width="200" :height="70" /> <progress1 :width="200" :height="70" />
<div class="flex flex-1 justify-between"> <div class="flex flex-1 justify-between">
<count-item label="景区当前人数" :count="35600" suffix="张" /> <count-item label="景区当前人数" :count="35600" suffix="张" />
<count-item label="景区最大承载" :count="35600" suffix="人" /> <count-item label="景区最大承载" :count="35600" suffix="人" />
@@ -36,9 +36,9 @@
<Title1 title="停车信息" /> <Title1 title="停车信息" />
<div class="flex"> <div class="flex">
<div class="flex"> <div class="flex">
<FProgress :width="140" :height="70" /> <progress1 :width="140" :height="70" />
<FProgress :width="140" :height="70" /> <progress1 :width="140" :height="70" />
<FProgress :width="140" :height="70" /> <progress1 :width="140" :height="70" />
</div> </div>
<div class="ml-20 flex flex-1 justify-between"> <div class="ml-20 flex flex-1 justify-between">
<count-item label="总停车场数" :count="561" suffix="个" /> <count-item label="总停车场数" :count="561" suffix="个" />
@@ -47,28 +47,178 @@
</div> </div>
<div class="flex"> <div class="flex">
<div class="border flex-1"> <div class="border flex-1">
<div class="pt-10">
<Title3 title="今日景区承载量" /> <Title3 title="今日景区承载量" />
<Line :width="350" :height="310" /> </div>
<Line :width="350" :height="300" />
</div> </div>
<div class="border flex-1"> <div class="border flex-1">
<div class="pt-10">
<Title3 title="车辆归属地占比" /> <Title3 title="车辆归属地占比" />
<Pie :width="350" :height="310" /> </div>
<PieRow :width="340" :height="300" />
</div> </div>
</div> </div>
</div> </div>
<div class="box-2"> <div class="box-2">
<Title1 title="安全信息 " /> <Title1 title="安全信息 " />
<div class="top flex">
<count-item label="当前告警总数" :count="561" suffix="次" />
<count-item label="安全告警总数" :count="561" suffix="次" />
<count-item label="已解除告警数" :count="561" />
</div>
<div class="border flex-1">
<div class="pt-10">
<Title3 title="今日景区承载量" />
</div>
<PieRow :width="350" :height="300" />
</div> </div>
</div> </div>
</div> </div>
<div class="flex mt-10">
<div class="box-3 mr-10">
<Title1 title="交通信息" />
<div class="top flex">
<count-item label="总通景路段" :count="35600" suffix="张" />
<count-item label="通景路段拥堵数" :count="35600" suffix="人" />
<count-item label="拥堵开始时间" :count="35600" suffix="人" />
<count-item label="拥堵持续时间" :count="35600" suffix="S" />
</div>
<div class="flex">
<div class="border">
<Line :width="260" :height="330" />
</div>
<div class="border">
<PieCol :width="230" :height="330" />
</div>
<div class="border">
<PieCol :width="230" :height="330" />
</div>
</div>
</div>
<div class="box-4 mr-10">
<Title1 title="用户画像" />
<div class="flex">
<div class="border">1</div>
<div class="border">2</div>
<div class="border">3</div>
</div>
</div>
<div class="box-5">
<Title1 title="车船信息" />
<div class="flex mb-6">
<div class="border pt-10 pb-10">
<Title2 title="车车车车车车" />
<div class="car-box mt-10">
<div class="pr-20">
<div class="label">车总数</div>
<div class="value">130</div>
</div>
<div>
<div class="label">今日累计运营(班次)</div>
<div class="value">130</div>
</div>
</div>
<div class="progress-box">
<span class="text">运营130辆</span>
<div class="progress">
<el-progress
:percentage="50"
:show-text="false"
color="linear-gradient(to right, rgba(0,150,255,0) 0%, #F15A25 100%)"
/>
</div>
<span class="value">空余100辆</span>
</div>
</div>
<div class="border pt-10 pb-10">
<Title2 title="船船船船船船" />
<div class="car-box mt-10">
<div class="pr-20">
<div class="label">车总数</div>
<div class="value">130</div>
</div>
<div>
<div class="label">今日累计运营(班次)</div>
<div class="value">130</div>
</div>
</div>
<div class="progress-box">
<span class="text">运营130辆</span>
<div class="progress">
<el-progress
:percentage="50"
:show-text="false"
color="linear-gradient(to right, rgba(0,150,255,0) 0%, #F15A25 100%)"
/>
</div>
<span class="value">空余100辆</span>
</div>
</div>
</div>
<div class="border">
<div id="car-ship" class="car-ship" />
<img class="full" src="@/assets/images/full.png" @click="show = true" />
</div>
</div>
</div>
</div>
<BigCarShipMap v-model="show" />
</template> </template>
<script setup> <script setup>
import CountItem from './count-item.vue' import progress1 from './progress-1.vue'
import FProgress from './progress-1.vue' import { useMap } from '@/hooks/map'
import carIcon from '@/assets/images/car.png'
import shipIcon from '@/assets/images/ship.png'
import BigCarShipMap from './big-car-ship-map.vue'
const { initMap, addMarker } = useMap()
let show = ref(false)
onMounted(() => {
initMap('car-ship', 109.491961, 31.024285, 13)
addMarker(carIcon, [109.491045, 31.028725], [36, 50])
addMarker(carIcon, [109.483266, 31.024718], [36, 50])
addMarker(shipIcon, [109.479062, 31.021499], [36, 50])
addMarker(shipIcon, [109.488907, 31.017476], [36, 50])
})
</script> </script>
<style scoped lang="scss"> <style scoped lang="scss">
:deep(.BMap_cpyCtrl) {
display: none;
}
:deep(.anchorBL) {
display: none;
}
.dialog {
:deep(.el-dialog) {
width: vw(2540);
height: vh(904);
}
}
.progress-box {
margin-top: vh(10);
height: vh(20);
display: flex;
align-items: center;
justify-content: center;
background: linear-gradient(to right, rgba(0, 150, 255, 0) 0%, rgba(0, 150, 255, 0.17) 100%);
.text {
margin-right: vw(10);
font-weight: 400;
font-size: vw(14);
color: #ffffff;
}
.progress {
width: vw(100);
}
.value {
margin-left: vw(10);
font-weight: 400;
font-size: vw(14);
color: #f15a25;
}
}
.container { .container {
flex: 1; flex: 1;
margin: vh(120) vw(10) 0 vw(10); margin: vh(120) vw(10) 0 vw(10);
@@ -80,6 +230,8 @@
background: linear-gradient(321deg, #0b2f64 0%, #062b57 100%); background: linear-gradient(321deg, #0b2f64 0%, #062b57 100%);
} }
.border { .border {
position: relative;
overflow: hidden;
padding: 0 vw(10); padding: 0 vw(10);
margin: 0 vw(10); margin: 0 vw(10);
box-sizing: border-box; box-sizing: border-box;
@@ -101,5 +253,52 @@
width: vw(440); width: vw(440);
height: vh(475); height: vh(475);
} }
.box-3 {
@extend .bg;
width: vw(850);
height: vh(465);
}
.box-4 {
@extend .bg;
width: vw(850);
height: vh(465);
}
.box-5 {
@extend .bg;
width: vw(670);
height: vh(465);
}
.car-box {
width: vw(350);
height: vh(74);
padding-left: vw(75);
display: flex;
align-items: center;
background-image: url('@/assets/images/icon-6.png');
background-size: 100% 100%;
.label {
font-weight: 400;
font-size: vw(14);
color: #fff;
}
.value {
font-weight: bold;
font-size: vw(24);
color: #02f9fa;
margin-top: vh(10);
}
}
.car-ship {
width: vw(630);
height: vh(230);
}
.full {
cursor: pointer;
position: absolute;
right: vw(20);
bottom: vh(20);
width: vw(50);
z-index: 999;
}
} }
</style> </style>

View File

@@ -23,6 +23,7 @@ export default defineConfig({
}) })
// vueDevTools(), // vueDevTools(),
], ],
base: '/largeScreen/',
server: { server: {
hmr: true, hmr: true,
host: '0.0.0.0' host: '0.0.0.0'