From a42e22161e78de69e18ea1d9485f83a98679a49b Mon Sep 17 00:00:00 2001 From: xlmessage <3240982126@qq.com> Date: Wed, 12 Feb 2025 18:48:17 +0800 Subject: [PATCH] =?UTF-8?q?=E8=82=A1=E7=A5=A8k=E7=BA=BF=E5=9B=BE=E4=BF=A1?= =?UTF-8?q?=E6=81=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitignore | 30 + .vscode/extensions.json | 3 + README.md | 33 + env.d.ts | 1 + index.html | 20 + package-lock.json | 3513 +++++++++++++++++++++++++++++++ package.json | 32 + public/favicon.ico | Bin 0 -> 4286 bytes src/App.vue | 9 + src/assets/base.css | 101 + src/assets/logo.svg | 1 + src/assets/main.css | 35 + src/end/DayDesign.vue | 840 ++++++++ src/end/EndDesign.vue | 957 +++++++++ src/end/NewDesign.vue | 1752 +++++++++++++++ src/end/NodataView.vue | 32 + src/end/computedInfo.js | 293 +++ src/endnew/NewStyleDesign.vue | 1767 ++++++++++++++++ src/endtype/HourLineWrapper.vue | 32 + src/main.ts | 24 + src/router/index.ts | 63 + src/shims-vue.d.ts | 5 + src/store/index.ts | 5 + src/store/usestylestore.ts | 0 src/store/usethemestore.ts | 30 + src/uilts/vscode.ts | 2 + src/utils/echarts.js | 37 + src/utils/http.js | 45 + src/utils/request.js | 57 + src/utils/vscode.ts | 2 + src/views/HomeView.vue | 240 +++ src/views/TheNewView.vue | 1237 +++++++++++ tsconfig.app.json | 12 + tsconfig.json | 11 + tsconfig.node.json | 18 + vite.config.ts | 30 + 36 files changed, 11269 insertions(+) create mode 100644 .gitignore create mode 100644 .vscode/extensions.json create mode 100644 README.md create mode 100644 env.d.ts create mode 100644 index.html create mode 100644 package-lock.json create mode 100644 package.json create mode 100644 public/favicon.ico create mode 100644 src/App.vue create mode 100644 src/assets/base.css create mode 100644 src/assets/logo.svg create mode 100644 src/assets/main.css create mode 100644 src/end/DayDesign.vue create mode 100644 src/end/EndDesign.vue create mode 100644 src/end/NewDesign.vue create mode 100644 src/end/NodataView.vue create mode 100644 src/end/computedInfo.js create mode 100644 src/endnew/NewStyleDesign.vue create mode 100644 src/endtype/HourLineWrapper.vue create mode 100644 src/main.ts create mode 100644 src/router/index.ts create mode 100644 src/shims-vue.d.ts create mode 100644 src/store/index.ts create mode 100644 src/store/usestylestore.ts create mode 100644 src/store/usethemestore.ts create mode 100644 src/uilts/vscode.ts create mode 100644 src/utils/echarts.js create mode 100644 src/utils/http.js create mode 100644 src/utils/request.js create mode 100644 src/utils/vscode.ts create mode 100644 src/views/HomeView.vue create mode 100644 src/views/TheNewView.vue create mode 100644 tsconfig.app.json create mode 100644 tsconfig.json create mode 100644 tsconfig.node.json create mode 100644 vite.config.ts diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..8ee54e8 --- /dev/null +++ b/.gitignore @@ -0,0 +1,30 @@ +# Logs +logs +*.log +npm-debug.log* +yarn-debug.log* +yarn-error.log* +pnpm-debug.log* +lerna-debug.log* + +node_modules +.DS_Store +dist +dist-ssr +coverage +*.local + +/cypress/videos/ +/cypress/screenshots/ + +# Editor directories and files +.vscode/* +!.vscode/extensions.json +.idea +*.suo +*.ntvs* +*.njsproj +*.sln +*.sw? + +*.tsbuildinfo diff --git a/.vscode/extensions.json b/.vscode/extensions.json new file mode 100644 index 0000000..a7cea0b --- /dev/null +++ b/.vscode/extensions.json @@ -0,0 +1,3 @@ +{ + "recommendations": ["Vue.volar"] +} diff --git a/README.md b/README.md new file mode 100644 index 0000000..abe83bc --- /dev/null +++ b/README.md @@ -0,0 +1,33 @@ +# asideviewts + +This template should help get you started developing with Vue 3 in Vite. + +## Recommended IDE Setup + +[VSCode](https://code.visualstudio.com/) + [Volar](https://marketplace.visualstudio.com/items?itemName=Vue.volar) (and disable Vetur). + +## Type Support for `.vue` Imports in TS + +TypeScript cannot handle type information for `.vue` imports by default, so we replace the `tsc` CLI with `vue-tsc` for type checking. In editors, we need [Volar](https://marketplace.visualstudio.com/items?itemName=Vue.volar) to make the TypeScript language service aware of `.vue` types. + +## Customize configuration + +See [Vite Configuration Reference](https://vite.dev/config/). + +## Project Setup + +```sh +npm install +``` + +### Compile and Hot-Reload for Development + +```sh +npm run dev +``` + +### Type-Check, Compile and Minify for Production + +```sh +npm run build +``` diff --git a/env.d.ts b/env.d.ts new file mode 100644 index 0000000..11f02fe --- /dev/null +++ b/env.d.ts @@ -0,0 +1 @@ +/// <reference types="vite/client" /> diff --git a/index.html b/index.html new file mode 100644 index 0000000..fbbd0b2 --- /dev/null +++ b/index.html @@ -0,0 +1,20 @@ +<!DOCTYPE html> +<html lang=""> + <head> + <meta charset="UTF-8"> + <link rel="icon" href="/favicon.ico"> + <meta name="viewport" content="width=device-width, initial-scale=1.0"> + <title>Vite App</title> + <style> + body{ + margin: 0; + padding: 0; + overflow: hidden; + } + </style> + </head> + <body> + <div id="app"></div> + <script type="module" src="/src/main.ts"></script> + </body> +</html> diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 0000000..6c3b45c --- /dev/null +++ b/package-lock.json @@ -0,0 +1,3513 @@ +{ + "name": "asideviewts", + "version": "0.0.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "asideviewts", + "version": "0.0.0", + "dependencies": { + "axios": "^1.7.9", + "echarts": "^5.6.0", + "element-plus": "^2.9.1", + "pinia": "^2.3.1", + "vue": "^3.5.13", + "vue-router": "^4.5.0" + }, + "devDependencies": { + "@tsconfig/node22": "^22.0.0", + "@types/node": "^22.10.2", + "@vitejs/plugin-vue": "^5.2.1", + "@vue/tsconfig": "^0.7.0", + "npm-run-all2": "^7.0.2", + "typescript": "~5.6.3", + "vite": "^6.0.5", + "vite-plugin-vue-devtools": "^7.6.8", + "vue-tsc": "^2.1.10" + } + }, + "node_modules/@ampproject/remapping": { + "version": "2.3.0", + "resolved": "https://registry.npmmirror.com/@ampproject/remapping/-/remapping-2.3.0.tgz", + "integrity": "sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.24" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@antfu/utils": { + "version": "0.7.10", + "resolved": "https://registry.npmmirror.com/@antfu/utils/-/utils-0.7.10.tgz", + "integrity": "sha512-+562v9k4aI80m1+VuMHehNJWLOFjBnXn3tdOitzD0il5b7smkSBal4+a3oKiQTbrwMmN/TBUMDvbdoWDehgOww==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/antfu" + } + }, + "node_modules/@babel/code-frame": { + "version": "7.26.2", + "resolved": "https://registry.npmmirror.com/@babel/code-frame/-/code-frame-7.26.2.tgz", + "integrity": "sha512-RJlIHRueQgwWitWgF8OdFYGZX328Ax5BCemNGlqHfplnRT9ESi8JkFlvaVYbS+UubVY6dpv87Fs2u5M29iNFVQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-validator-identifier": "^7.25.9", + "js-tokens": "^4.0.0", + "picocolors": "^1.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/compat-data": { + "version": "7.26.3", + "resolved": "https://registry.npmmirror.com/@babel/compat-data/-/compat-data-7.26.3.tgz", + "integrity": "sha512-nHIxvKPniQXpmQLb0vhY3VaFb3S0YrTAwpOWJZh1wn3oJPjJk9Asva204PsBdmAE8vpzfHudT8DB0scYvy9q0g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/core": { + "version": "7.26.0", + "resolved": "https://registry.npmmirror.com/@babel/core/-/core-7.26.0.tgz", + "integrity": "sha512-i1SLeK+DzNnQ3LL/CswPCa/E5u4lh1k6IAEphON8F+cXt0t9euTshDru0q7/IqMa1PMPz5RnHuHscF8/ZJsStg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@ampproject/remapping": "^2.2.0", + "@babel/code-frame": "^7.26.0", + "@babel/generator": "^7.26.0", + "@babel/helper-compilation-targets": "^7.25.9", + "@babel/helper-module-transforms": "^7.26.0", + "@babel/helpers": "^7.26.0", + "@babel/parser": "^7.26.0", + "@babel/template": "^7.25.9", + "@babel/traverse": "^7.25.9", + "@babel/types": "^7.26.0", + "convert-source-map": "^2.0.0", + "debug": "^4.1.0", + "gensync": "^1.0.0-beta.2", + "json5": "^2.2.3", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/babel" + } + }, + "node_modules/@babel/generator": { + "version": "7.26.3", + "resolved": "https://registry.npmmirror.com/@babel/generator/-/generator-7.26.3.tgz", + "integrity": "sha512-6FF/urZvD0sTeO7k6/B15pMLC4CHUv1426lzr3N01aHJTl046uCAh9LXW/fzeXXjPNCJ6iABW5XaWOsIZB93aQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/parser": "^7.26.3", + "@babel/types": "^7.26.3", + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.25", + "jsesc": "^3.0.2" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-annotate-as-pure": { + "version": "7.25.9", + "resolved": "https://registry.npmmirror.com/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.25.9.tgz", + "integrity": "sha512-gv7320KBUFJz1RnylIg5WWYPRXKZ884AGkYpgpWW02TH66Dl+HaC1t1CKd0z3R4b6hdYEcmrNZHUmfCP+1u3/g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/types": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-compilation-targets": { + "version": "7.25.9", + "resolved": "https://registry.npmmirror.com/@babel/helper-compilation-targets/-/helper-compilation-targets-7.25.9.tgz", + "integrity": "sha512-j9Db8Suy6yV/VHa4qzrj9yZfZxhLWQdVnRlXxmKLYlhWUVB1sB2G5sxuWYXk/whHD9iW76PmNzxZ4UCnTQTVEQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/compat-data": "^7.25.9", + "@babel/helper-validator-option": "^7.25.9", + "browserslist": "^4.24.0", + "lru-cache": "^5.1.1", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-create-class-features-plugin": { + "version": "7.25.9", + "resolved": "https://registry.npmmirror.com/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.25.9.tgz", + "integrity": "sha512-UTZQMvt0d/rSz6KI+qdu7GQze5TIajwTS++GUozlw8VBJDEOAqSXwm1WvmYEZwqdqSGQshRocPDqrt4HBZB3fQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.25.9", + "@babel/helper-member-expression-to-functions": "^7.25.9", + "@babel/helper-optimise-call-expression": "^7.25.9", + "@babel/helper-replace-supers": "^7.25.9", + "@babel/helper-skip-transparent-expression-wrappers": "^7.25.9", + "@babel/traverse": "^7.25.9", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-member-expression-to-functions": { + "version": "7.25.9", + "resolved": "https://registry.npmmirror.com/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.25.9.tgz", + "integrity": "sha512-wbfdZ9w5vk0C0oyHqAJbc62+vet5prjj01jjJ8sKn3j9h3MQQlflEdXYvuqRWjHnM12coDEqiC1IRCi0U/EKwQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/traverse": "^7.25.9", + "@babel/types": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-module-imports": { + "version": "7.25.9", + "resolved": "https://registry.npmmirror.com/@babel/helper-module-imports/-/helper-module-imports-7.25.9.tgz", + "integrity": "sha512-tnUA4RsrmflIM6W6RFTLFSXITtl0wKjgpnLgXyowocVPrbYrLUXSBXDgTs8BlbmIzIdlBySRQjINYs2BAkiLtw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/traverse": "^7.25.9", + "@babel/types": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-module-transforms": { + "version": "7.26.0", + "resolved": "https://registry.npmmirror.com/@babel/helper-module-transforms/-/helper-module-transforms-7.26.0.tgz", + "integrity": "sha512-xO+xu6B5K2czEnQye6BHA7DolFFmS3LB7stHZFaOLb1pAwO1HWLS8fXA+eh0A2yIvltPVmx3eNNDBJA2SLHXFw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-module-imports": "^7.25.9", + "@babel/helper-validator-identifier": "^7.25.9", + "@babel/traverse": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-optimise-call-expression": { + "version": "7.25.9", + "resolved": "https://registry.npmmirror.com/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.25.9.tgz", + "integrity": "sha512-FIpuNaz5ow8VyrYcnXQTDRGvV6tTjkNtCK/RYNDXGSLlUD6cBuQTSw43CShGxjvfBTfcUA/r6UhUCbtYqkhcuQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/types": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-plugin-utils": { + "version": "7.25.9", + "resolved": "https://registry.npmmirror.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.25.9.tgz", + "integrity": "sha512-kSMlyUVdWe25rEsRGviIgOWnoT/nfABVWlqt9N19/dIPWViAOW2s9wznP5tURbs/IDuNk4gPy3YdYRgH3uxhBw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-replace-supers": { + "version": "7.25.9", + "resolved": "https://registry.npmmirror.com/@babel/helper-replace-supers/-/helper-replace-supers-7.25.9.tgz", + "integrity": "sha512-IiDqTOTBQy0sWyeXyGSC5TBJpGFXBkRynjBeXsvbhQFKj2viwJC76Epz35YLU1fpe/Am6Vppb7W7zM4fPQzLsQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-member-expression-to-functions": "^7.25.9", + "@babel/helper-optimise-call-expression": "^7.25.9", + "@babel/traverse": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-skip-transparent-expression-wrappers": { + "version": "7.25.9", + "resolved": "https://registry.npmmirror.com/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.25.9.tgz", + "integrity": "sha512-K4Du3BFa3gvyhzgPcntrkDgZzQaq6uozzcpGbOO1OEJaI+EJdqWIMTLgFgQf6lrfiDFo5FU+BxKepI9RmZqahA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/traverse": "^7.25.9", + "@babel/types": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-string-parser": { + "version": "7.25.9", + "resolved": "https://registry.npmmirror.com/@babel/helper-string-parser/-/helper-string-parser-7.25.9.tgz", + "integrity": "sha512-4A/SCr/2KLd5jrtOMFzaKjVtAei3+2r/NChoBNoZ3EyP/+GlhoaEGoWOZUmFmoITP7zOJyHIMm+DYRd8o3PvHA==", + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-identifier": { + "version": "7.25.9", + "resolved": "https://registry.npmmirror.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.25.9.tgz", + "integrity": "sha512-Ed61U6XJc3CVRfkERJWDz4dJwKe7iLmmJsbOGu9wSloNSFttHV0I8g6UAgb7qnK5ly5bGLPd4oXZlxCdANBOWQ==", + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-option": { + "version": "7.25.9", + "resolved": "https://registry.npmmirror.com/@babel/helper-validator-option/-/helper-validator-option-7.25.9.tgz", + "integrity": "sha512-e/zv1co8pp55dNdEcCynfj9X7nyUKUXoUEwfXqaZt0omVOmDe9oOTdKStH4GmAw6zxMFs50ZayuMfHDKlO7Tfw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helpers": { + "version": "7.26.0", + "resolved": "https://registry.npmmirror.com/@babel/helpers/-/helpers-7.26.0.tgz", + "integrity": "sha512-tbhNuIxNcVb21pInl3ZSjksLCvgdZy9KwJ8brv993QtIVKJBBkYXz4q4ZbAv31GdnC+R90np23L5FbEBlthAEw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/template": "^7.25.9", + "@babel/types": "^7.26.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/parser": { + "version": "7.26.3", + "resolved": "https://registry.npmmirror.com/@babel/parser/-/parser-7.26.3.tgz", + "integrity": "sha512-WJ/CvmY8Mea8iDXo6a7RK2wbmJITT5fN3BEkRuFlxVyNx8jOKIIhmC4fSkTcPcf8JyavbBwIe6OpiCOBXt/IcA==", + "license": "MIT", + "dependencies": { + "@babel/types": "^7.26.3" + }, + "bin": { + "parser": "bin/babel-parser.js" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@babel/plugin-proposal-decorators": { + "version": "7.25.9", + "resolved": "https://registry.npmmirror.com/@babel/plugin-proposal-decorators/-/plugin-proposal-decorators-7.25.9.tgz", + "integrity": "sha512-smkNLL/O1ezy9Nhy4CNosc4Va+1wo5w4gzSZeLe6y6dM4mmHfYOCPolXQPHQxonZCF+ZyebxN9vqOolkYrSn5g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-create-class-features-plugin": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9", + "@babel/plugin-syntax-decorators": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-decorators": { + "version": "7.25.9", + "resolved": "https://registry.npmmirror.com/@babel/plugin-syntax-decorators/-/plugin-syntax-decorators-7.25.9.tgz", + "integrity": "sha512-ryzI0McXUPJnRCvMo4lumIKZUzhYUO/ScI+Mz4YVaTLt04DHNSjEUjKVvbzQjZFLuod/cYEc07mJWhzl6v4DPg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-import-attributes": { + "version": "7.26.0", + "resolved": "https://registry.npmmirror.com/@babel/plugin-syntax-import-attributes/-/plugin-syntax-import-attributes-7.26.0.tgz", + "integrity": "sha512-e2dttdsJ1ZTpi3B9UYGLw41hifAubg19AtCu/2I/F1QNVclOBr1dYpTdmdyZ84Xiz43BS/tCUkMAZNLv12Pi+A==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-import-meta": { + "version": "7.10.4", + "resolved": "https://registry.npmmirror.com/@babel/plugin-syntax-import-meta/-/plugin-syntax-import-meta-7.10.4.tgz", + "integrity": "sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.10.4" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-jsx": { + "version": "7.25.9", + "resolved": "https://registry.npmmirror.com/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.25.9.tgz", + "integrity": "sha512-ld6oezHQMZsZfp6pWtbjaNDF2tiiCYYDqQszHt5VV437lewP9aSi2Of99CK0D0XB21k7FLgnLcmQKyKzynfeAA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-typescript": { + "version": "7.25.9", + "resolved": "https://registry.npmmirror.com/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.25.9.tgz", + "integrity": "sha512-hjMgRy5hb8uJJjUcdWunWVcoi9bGpJp8p5Ol1229PoN6aytsLwNMgmdftO23wnCLMfVmTwZDWMPNq/D1SY60JQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-typescript": { + "version": "7.26.3", + "resolved": "https://registry.npmmirror.com/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.26.3.tgz", + "integrity": "sha512-6+5hpdr6mETwSKjmJUdYw0EIkATiQhnELWlE3kJFBwSg/BGIVwVaVbX+gOXBCdc7Ln1RXZxyWGecIXhUfnl7oA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.25.9", + "@babel/helper-create-class-features-plugin": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9", + "@babel/helper-skip-transparent-expression-wrappers": "^7.25.9", + "@babel/plugin-syntax-typescript": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/template": { + "version": "7.25.9", + "resolved": "https://registry.npmmirror.com/@babel/template/-/template-7.25.9.tgz", + "integrity": "sha512-9DGttpmPvIxBb/2uwpVo3dqJ+O6RooAFOS+lB+xDqoE2PVCE8nfoHMdZLpfCQRLwvohzXISPZcgxt80xLfsuwg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.25.9", + "@babel/parser": "^7.25.9", + "@babel/types": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/traverse": { + "version": "7.26.4", + "resolved": "https://registry.npmmirror.com/@babel/traverse/-/traverse-7.26.4.tgz", + "integrity": "sha512-fH+b7Y4p3yqvApJALCPJcwb0/XaOSgtK4pzV6WVjPR5GLFQBRI7pfoX2V2iM48NXvX07NUxxm1Vw98YjqTcU5w==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.26.2", + "@babel/generator": "^7.26.3", + "@babel/parser": "^7.26.3", + "@babel/template": "^7.25.9", + "@babel/types": "^7.26.3", + "debug": "^4.3.1", + "globals": "^11.1.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/types": { + "version": "7.26.3", + "resolved": "https://registry.npmmirror.com/@babel/types/-/types-7.26.3.tgz", + "integrity": "sha512-vN5p+1kl59GVKMvTHt55NzzmYVxprfJD+ql7U9NFIfKCBkYE55LYtS+WtPlaYOyzydrKI8Nezd+aZextrd+FMA==", + "license": "MIT", + "dependencies": { + "@babel/helper-string-parser": "^7.25.9", + "@babel/helper-validator-identifier": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@ctrl/tinycolor": { + "version": "3.6.1", + "resolved": "https://registry.npmmirror.com/@ctrl/tinycolor/-/tinycolor-3.6.1.tgz", + "integrity": "sha512-SITSV6aIXsuVNV3f3O0f2n/cgyEDWoSqtZMYiAmcsYHydcKrOz3gUxB/iXd/Qf08+IZX4KpgNbvUdMBmWz+kcA==", + "license": "MIT", + "engines": { + "node": ">=10" + } + }, + "node_modules/@element-plus/icons-vue": { + "version": "2.3.1", + "resolved": "https://registry.npmmirror.com/@element-plus/icons-vue/-/icons-vue-2.3.1.tgz", + "integrity": "sha512-XxVUZv48RZAd87ucGS48jPf6pKu0yV5UCg9f4FFwtrYxXOwWuVJo6wOvSLKEoMQKjv8GsX/mhP6UsC1lRwbUWg==", + "license": "MIT", + "peerDependencies": { + "vue": "^3.2.0" + } + }, + "node_modules/@esbuild/aix-ppc64": { + "version": "0.24.2", + "resolved": "https://registry.npmmirror.com/@esbuild/aix-ppc64/-/aix-ppc64-0.24.2.tgz", + "integrity": "sha512-thpVCb/rhxE/BnMLQ7GReQLLN8q9qbHmI55F4489/ByVg2aQaQ6kbcLb6FHkocZzQhxc4gx0sCk0tJkKBFzDhA==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "aix" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-arm": { + "version": "0.24.2", + "resolved": "https://registry.npmmirror.com/@esbuild/android-arm/-/android-arm-0.24.2.tgz", + "integrity": "sha512-tmwl4hJkCfNHwFB3nBa8z1Uy3ypZpxqxfTQOcHX+xRByyYgunVbZ9MzUUfb0RxaHIMnbHagwAxuTL+tnNM+1/Q==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-arm64": { + "version": "0.24.2", + "resolved": "https://registry.npmmirror.com/@esbuild/android-arm64/-/android-arm64-0.24.2.tgz", + "integrity": "sha512-cNLgeqCqV8WxfcTIOeL4OAtSmL8JjcN6m09XIgro1Wi7cF4t/THaWEa7eL5CMoMBdjoHOTh/vwTO/o2TRXIyzg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-x64": { + "version": "0.24.2", + "resolved": "https://registry.npmmirror.com/@esbuild/android-x64/-/android-x64-0.24.2.tgz", + "integrity": "sha512-B6Q0YQDqMx9D7rvIcsXfmJfvUYLoP722bgfBlO5cGvNVb5V/+Y7nhBE3mHV9OpxBf4eAS2S68KZztiPaWq4XYw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/darwin-arm64": { + "version": "0.24.2", + "resolved": "https://registry.npmmirror.com/@esbuild/darwin-arm64/-/darwin-arm64-0.24.2.tgz", + "integrity": "sha512-kj3AnYWc+CekmZnS5IPu9D+HWtUI49hbnyqk0FLEJDbzCIQt7hg7ucF1SQAilhtYpIujfaHr6O0UHlzzSPdOeA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/darwin-x64": { + "version": "0.24.2", + "resolved": "https://registry.npmmirror.com/@esbuild/darwin-x64/-/darwin-x64-0.24.2.tgz", + "integrity": "sha512-WeSrmwwHaPkNR5H3yYfowhZcbriGqooyu3zI/3GGpF8AyUdsrrP0X6KumITGA9WOyiJavnGZUwPGvxvwfWPHIA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/freebsd-arm64": { + "version": "0.24.2", + "resolved": "https://registry.npmmirror.com/@esbuild/freebsd-arm64/-/freebsd-arm64-0.24.2.tgz", + "integrity": "sha512-UN8HXjtJ0k/Mj6a9+5u6+2eZ2ERD7Edt1Q9IZiB5UZAIdPnVKDoG7mdTVGhHJIeEml60JteamR3qhsr1r8gXvg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/freebsd-x64": { + "version": "0.24.2", + "resolved": "https://registry.npmmirror.com/@esbuild/freebsd-x64/-/freebsd-x64-0.24.2.tgz", + "integrity": "sha512-TvW7wE/89PYW+IevEJXZ5sF6gJRDY/14hyIGFXdIucxCsbRmLUcjseQu1SyTko+2idmCw94TgyaEZi9HUSOe3Q==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-arm": { + "version": "0.24.2", + "resolved": "https://registry.npmmirror.com/@esbuild/linux-arm/-/linux-arm-0.24.2.tgz", + "integrity": "sha512-n0WRM/gWIdU29J57hJyUdIsk0WarGd6To0s+Y+LwvlC55wt+GT/OgkwoXCXvIue1i1sSNWblHEig00GBWiJgfA==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-arm64": { + "version": "0.24.2", + "resolved": "https://registry.npmmirror.com/@esbuild/linux-arm64/-/linux-arm64-0.24.2.tgz", + "integrity": "sha512-7HnAD6074BW43YvvUmE/35Id9/NB7BeX5EoNkK9obndmZBUk8xmJJeU7DwmUeN7tkysslb2eSl6CTrYz6oEMQg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-ia32": { + "version": "0.24.2", + "resolved": "https://registry.npmmirror.com/@esbuild/linux-ia32/-/linux-ia32-0.24.2.tgz", + "integrity": "sha512-sfv0tGPQhcZOgTKO3oBE9xpHuUqguHvSo4jl+wjnKwFpapx+vUDcawbwPNuBIAYdRAvIDBfZVvXprIj3HA+Ugw==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-loong64": { + "version": "0.24.2", + "resolved": "https://registry.npmmirror.com/@esbuild/linux-loong64/-/linux-loong64-0.24.2.tgz", + "integrity": "sha512-CN9AZr8kEndGooS35ntToZLTQLHEjtVB5n7dl8ZcTZMonJ7CCfStrYhrzF97eAecqVbVJ7APOEe18RPI4KLhwQ==", + "cpu": [ + "loong64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-mips64el": { + "version": "0.24.2", + "resolved": "https://registry.npmmirror.com/@esbuild/linux-mips64el/-/linux-mips64el-0.24.2.tgz", + "integrity": "sha512-iMkk7qr/wl3exJATwkISxI7kTcmHKE+BlymIAbHO8xanq/TjHaaVThFF6ipWzPHryoFsesNQJPE/3wFJw4+huw==", + "cpu": [ + "mips64el" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-ppc64": { + "version": "0.24.2", + "resolved": "https://registry.npmmirror.com/@esbuild/linux-ppc64/-/linux-ppc64-0.24.2.tgz", + "integrity": "sha512-shsVrgCZ57Vr2L8mm39kO5PPIb+843FStGt7sGGoqiiWYconSxwTiuswC1VJZLCjNiMLAMh34jg4VSEQb+iEbw==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-riscv64": { + "version": "0.24.2", + "resolved": "https://registry.npmmirror.com/@esbuild/linux-riscv64/-/linux-riscv64-0.24.2.tgz", + "integrity": "sha512-4eSFWnU9Hhd68fW16GD0TINewo1L6dRrB+oLNNbYyMUAeOD2yCK5KXGK1GH4qD/kT+bTEXjsyTCiJGHPZ3eM9Q==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-s390x": { + "version": "0.24.2", + "resolved": "https://registry.npmmirror.com/@esbuild/linux-s390x/-/linux-s390x-0.24.2.tgz", + "integrity": "sha512-S0Bh0A53b0YHL2XEXC20bHLuGMOhFDO6GN4b3YjRLK//Ep3ql3erpNcPlEFed93hsQAjAQDNsvcK+hV90FubSw==", + "cpu": [ + "s390x" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-x64": { + "version": "0.24.2", + "resolved": "https://registry.npmmirror.com/@esbuild/linux-x64/-/linux-x64-0.24.2.tgz", + "integrity": "sha512-8Qi4nQcCTbLnK9WoMjdC9NiTG6/E38RNICU6sUNqK0QFxCYgoARqVqxdFmWkdonVsvGqWhmm7MO0jyTqLqwj0Q==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/netbsd-arm64": { + "version": "0.24.2", + "resolved": "https://registry.npmmirror.com/@esbuild/netbsd-arm64/-/netbsd-arm64-0.24.2.tgz", + "integrity": "sha512-wuLK/VztRRpMt9zyHSazyCVdCXlpHkKm34WUyinD2lzK07FAHTq0KQvZZlXikNWkDGoT6x3TD51jKQ7gMVpopw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/netbsd-x64": { + "version": "0.24.2", + "resolved": "https://registry.npmmirror.com/@esbuild/netbsd-x64/-/netbsd-x64-0.24.2.tgz", + "integrity": "sha512-VefFaQUc4FMmJuAxmIHgUmfNiLXY438XrL4GDNV1Y1H/RW3qow68xTwjZKfj/+Plp9NANmzbH5R40Meudu8mmw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openbsd-arm64": { + "version": "0.24.2", + "resolved": "https://registry.npmmirror.com/@esbuild/openbsd-arm64/-/openbsd-arm64-0.24.2.tgz", + "integrity": "sha512-YQbi46SBct6iKnszhSvdluqDmxCJA+Pu280Av9WICNwQmMxV7nLRHZfjQzwbPs3jeWnuAhE9Jy0NrnJ12Oz+0A==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openbsd-x64": { + "version": "0.24.2", + "resolved": "https://registry.npmmirror.com/@esbuild/openbsd-x64/-/openbsd-x64-0.24.2.tgz", + "integrity": "sha512-+iDS6zpNM6EnJyWv0bMGLWSWeXGN/HTaF/LXHXHwejGsVi+ooqDfMCCTerNFxEkM3wYVcExkeGXNqshc9iMaOA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/sunos-x64": { + "version": "0.24.2", + "resolved": "https://registry.npmmirror.com/@esbuild/sunos-x64/-/sunos-x64-0.24.2.tgz", + "integrity": "sha512-hTdsW27jcktEvpwNHJU4ZwWFGkz2zRJUz8pvddmXPtXDzVKTTINmlmga3ZzwcuMpUvLw7JkLy9QLKyGpD2Yxig==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "sunos" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-arm64": { + "version": "0.24.2", + "resolved": "https://registry.npmmirror.com/@esbuild/win32-arm64/-/win32-arm64-0.24.2.tgz", + "integrity": "sha512-LihEQ2BBKVFLOC9ZItT9iFprsE9tqjDjnbulhHoFxYQtQfai7qfluVODIYxt1PgdoyQkz23+01rzwNwYfutxUQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-ia32": { + "version": "0.24.2", + "resolved": "https://registry.npmmirror.com/@esbuild/win32-ia32/-/win32-ia32-0.24.2.tgz", + "integrity": "sha512-q+iGUwfs8tncmFC9pcnD5IvRHAzmbwQ3GPS5/ceCyHdjXubwQWI12MKWSNSMYLJMq23/IUCvJMS76PDqXe1fxA==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-x64": { + "version": "0.24.2", + "resolved": "https://registry.npmmirror.com/@esbuild/win32-x64/-/win32-x64-0.24.2.tgz", + "integrity": "sha512-7VTgWzgMGvup6aSqDPLiW5zHaxYJGTO4OokMjIlrCtf+VpEL+cXKtCvg723iguPYI5oaUNdS+/V7OU2gvXVWEg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@floating-ui/core": { + "version": "1.6.8", + "resolved": "https://registry.npmmirror.com/@floating-ui/core/-/core-1.6.8.tgz", + "integrity": "sha512-7XJ9cPU+yI2QeLS+FCSlqNFZJq8arvswefkZrYI1yQBbftw6FyrZOxYSh+9S7z7TpeWlRt9zJ5IhM1WIL334jA==", + "license": "MIT", + "dependencies": { + "@floating-ui/utils": "^0.2.8" + } + }, + "node_modules/@floating-ui/dom": { + "version": "1.6.12", + "resolved": "https://registry.npmmirror.com/@floating-ui/dom/-/dom-1.6.12.tgz", + "integrity": "sha512-NP83c0HjokcGVEMeoStg317VD9W7eDlGK7457dMBANbKA6GJZdc7rjujdgqzTaz93jkGgc5P/jeWbaCHnMNc+w==", + "license": "MIT", + "dependencies": { + "@floating-ui/core": "^1.6.0", + "@floating-ui/utils": "^0.2.8" + } + }, + "node_modules/@floating-ui/utils": { + "version": "0.2.8", + "resolved": "https://registry.npmmirror.com/@floating-ui/utils/-/utils-0.2.8.tgz", + "integrity": "sha512-kym7SodPp8/wloecOpcmSnWJsK7M0E5Wg8UcFA+uO4B9s5d0ywXOEro/8HM9x0rW+TljRzul/14UYz3TleT3ig==", + "license": "MIT" + }, + "node_modules/@jridgewell/gen-mapping": { + "version": "0.3.8", + "resolved": "https://registry.npmmirror.com/@jridgewell/gen-mapping/-/gen-mapping-0.3.8.tgz", + "integrity": "sha512-imAbBGkb+ebQyxKgzv5Hu2nmROxoDOXHh80evxdoXNOrvAnVx7zimzc1Oo5h9RlfV4vPXaE2iM5pOFbvOCClWA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/set-array": "^1.2.1", + "@jridgewell/sourcemap-codec": "^1.4.10", + "@jridgewell/trace-mapping": "^0.3.24" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/resolve-uri": { + "version": "3.1.2", + "resolved": "https://registry.npmmirror.com/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", + "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/set-array": { + "version": "1.2.1", + "resolved": "https://registry.npmmirror.com/@jridgewell/set-array/-/set-array-1.2.1.tgz", + "integrity": "sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.5.0", + "resolved": "https://registry.npmmirror.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.0.tgz", + "integrity": "sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==", + "license": "MIT" + }, + "node_modules/@jridgewell/trace-mapping": { + "version": "0.3.25", + "resolved": "https://registry.npmmirror.com/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz", + "integrity": "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/resolve-uri": "^3.1.0", + "@jridgewell/sourcemap-codec": "^1.4.14" + } + }, + "node_modules/@polka/url": { + "version": "1.0.0-next.28", + "resolved": "https://registry.npmmirror.com/@polka/url/-/url-1.0.0-next.28.tgz", + "integrity": "sha512-8LduaNlMZGwdZ6qWrKlfa+2M4gahzFkprZiAt2TF8uS0qQgBizKXpXURqvTJ4WtmupWxaLqjRb2UCTe72mu+Aw==", + "dev": true, + "license": "MIT" + }, + "node_modules/@popperjs/core": { + "name": "@sxzz/popperjs-es", + "version": "2.11.7", + "resolved": "https://registry.npmmirror.com/@sxzz/popperjs-es/-/popperjs-es-2.11.7.tgz", + "integrity": "sha512-Ccy0NlLkzr0Ex2FKvh2X+OyERHXJ88XJ1MXtsI9y9fGexlaXaVTPzBCRBwIxFkORuOb+uBqeu+RqnpgYTEZRUQ==", + "license": "MIT", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/popperjs" + } + }, + "node_modules/@rollup/pluginutils": { + "version": "5.1.4", + "resolved": "https://registry.npmmirror.com/@rollup/pluginutils/-/pluginutils-5.1.4.tgz", + "integrity": "sha512-USm05zrsFxYLPdWWq+K3STlWiT/3ELn3RcV5hJMghpeAIhxfsUIg6mt12CBJBInWMV4VneoV7SfGv8xIwo2qNQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/estree": "^1.0.0", + "estree-walker": "^2.0.2", + "picomatch": "^4.0.2" + }, + "engines": { + "node": ">=14.0.0" + }, + "peerDependencies": { + "rollup": "^1.20.0||^2.0.0||^3.0.0||^4.0.0" + }, + "peerDependenciesMeta": { + "rollup": { + "optional": true + } + } + }, + "node_modules/@rollup/rollup-android-arm-eabi": { + "version": "4.29.1", + "resolved": "https://registry.npmmirror.com/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.29.1.tgz", + "integrity": "sha512-ssKhA8RNltTZLpG6/QNkCSge+7mBQGUqJRisZ2MDQcEGaK93QESEgWK2iOpIDZ7k9zPVkG5AS3ksvD5ZWxmItw==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@rollup/rollup-android-arm64": { + "version": "4.29.1", + "resolved": "https://registry.npmmirror.com/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.29.1.tgz", + "integrity": "sha512-CaRfrV0cd+NIIcVVN/jx+hVLN+VRqnuzLRmfmlzpOzB87ajixsN/+9L5xNmkaUUvEbI5BmIKS+XTwXsHEb65Ew==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@rollup/rollup-darwin-arm64": { + "version": "4.29.1", + "resolved": "https://registry.npmmirror.com/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.29.1.tgz", + "integrity": "sha512-2ORr7T31Y0Mnk6qNuwtyNmy14MunTAMx06VAPI6/Ju52W10zk1i7i5U3vlDRWjhOI5quBcrvhkCHyF76bI7kEw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@rollup/rollup-darwin-x64": { + "version": "4.29.1", + "resolved": "https://registry.npmmirror.com/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.29.1.tgz", + "integrity": "sha512-j/Ej1oanzPjmN0tirRd5K2/nncAhS9W6ICzgxV+9Y5ZsP0hiGhHJXZ2JQ53iSSjj8m6cRY6oB1GMzNn2EUt6Ng==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@rollup/rollup-freebsd-arm64": { + "version": "4.29.1", + "resolved": "https://registry.npmmirror.com/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.29.1.tgz", + "integrity": "sha512-91C//G6Dm/cv724tpt7nTyP+JdN12iqeXGFM1SqnljCmi5yTXriH7B1r8AD9dAZByHpKAumqP1Qy2vVNIdLZqw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ] + }, + "node_modules/@rollup/rollup-freebsd-x64": { + "version": "4.29.1", + "resolved": "https://registry.npmmirror.com/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.29.1.tgz", + "integrity": "sha512-hEioiEQ9Dec2nIRoeHUP6hr1PSkXzQaCUyqBDQ9I9ik4gCXQZjJMIVzoNLBRGet+hIUb3CISMh9KXuCcWVW/8w==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ] + }, + "node_modules/@rollup/rollup-linux-arm-gnueabihf": { + "version": "4.29.1", + "resolved": "https://registry.npmmirror.com/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.29.1.tgz", + "integrity": "sha512-Py5vFd5HWYN9zxBv3WMrLAXY3yYJ6Q/aVERoeUFwiDGiMOWsMs7FokXihSOaT/PMWUty/Pj60XDQndK3eAfE6A==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm-musleabihf": { + "version": "4.29.1", + "resolved": "https://registry.npmmirror.com/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.29.1.tgz", + "integrity": "sha512-RiWpGgbayf7LUcuSNIbahr0ys2YnEERD4gYdISA06wa0i8RALrnzflh9Wxii7zQJEB2/Eh74dX4y/sHKLWp5uQ==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm64-gnu": { + "version": "4.29.1", + "resolved": "https://registry.npmmirror.com/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.29.1.tgz", + "integrity": "sha512-Z80O+taYxTQITWMjm/YqNoe9d10OX6kDh8X5/rFCMuPqsKsSyDilvfg+vd3iXIqtfmp+cnfL1UrYirkaF8SBZA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm64-musl": { + "version": "4.29.1", + "resolved": "https://registry.npmmirror.com/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.29.1.tgz", + "integrity": "sha512-fOHRtF9gahwJk3QVp01a/GqS4hBEZCV1oKglVVq13kcK3NeVlS4BwIFzOHDbmKzt3i0OuHG4zfRP0YoG5OF/rA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-loongarch64-gnu": { + "version": "4.29.1", + "resolved": "https://registry.npmmirror.com/@rollup/rollup-linux-loongarch64-gnu/-/rollup-linux-loongarch64-gnu-4.29.1.tgz", + "integrity": "sha512-5a7q3tnlbcg0OodyxcAdrrCxFi0DgXJSoOuidFUzHZ2GixZXQs6Tc3CHmlvqKAmOs5eRde+JJxeIf9DonkmYkw==", + "cpu": [ + "loong64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-powerpc64le-gnu": { + "version": "4.29.1", + "resolved": "https://registry.npmmirror.com/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.29.1.tgz", + "integrity": "sha512-9b4Mg5Yfz6mRnlSPIdROcfw1BU22FQxmfjlp/CShWwO3LilKQuMISMTtAu/bxmmrE6A902W2cZJuzx8+gJ8e9w==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-riscv64-gnu": { + "version": "4.29.1", + "resolved": "https://registry.npmmirror.com/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.29.1.tgz", + "integrity": "sha512-G5pn0NChlbRM8OJWpJFMX4/i8OEU538uiSv0P6roZcbpe/WfhEO+AT8SHVKfp8qhDQzaz7Q+1/ixMy7hBRidnQ==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-s390x-gnu": { + "version": "4.29.1", + "resolved": "https://registry.npmmirror.com/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.29.1.tgz", + "integrity": "sha512-WM9lIkNdkhVwiArmLxFXpWndFGuOka4oJOZh8EP3Vb8q5lzdSCBuhjavJsw68Q9AKDGeOOIHYzYm4ZFvmWez5g==", + "cpu": [ + "s390x" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-x64-gnu": { + "version": "4.29.1", + "resolved": "https://registry.npmmirror.com/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.29.1.tgz", + "integrity": "sha512-87xYCwb0cPGZFoGiErT1eDcssByaLX4fc0z2nRM6eMtV9njAfEE6OW3UniAoDhX4Iq5xQVpE6qO9aJbCFumKYQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-x64-musl": { + "version": "4.29.1", + "resolved": "https://registry.npmmirror.com/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.29.1.tgz", + "integrity": "sha512-xufkSNppNOdVRCEC4WKvlR1FBDyqCSCpQeMMgv9ZyXqqtKBfkw1yfGMTUTs9Qsl6WQbJnsGboWCp7pJGkeMhKA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-win32-arm64-msvc": { + "version": "4.29.1", + "resolved": "https://registry.npmmirror.com/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.29.1.tgz", + "integrity": "sha512-F2OiJ42m77lSkizZQLuC+jiZ2cgueWQL5YC9tjo3AgaEw+KJmVxHGSyQfDUoYR9cci0lAywv2Clmckzulcq6ig==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-ia32-msvc": { + "version": "4.29.1", + "resolved": "https://registry.npmmirror.com/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.29.1.tgz", + "integrity": "sha512-rYRe5S0FcjlOBZQHgbTKNrqxCBUmgDJem/VQTCcTnA2KCabYSWQDrytOzX7avb79cAAweNmMUb/Zw18RNd4mng==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-x64-msvc": { + "version": "4.29.1", + "resolved": "https://registry.npmmirror.com/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.29.1.tgz", + "integrity": "sha512-+10CMg9vt1MoHj6x1pxyjPSMjHTIlqs8/tBztXvPAx24SKs9jwVnKqHJumlH/IzhaPUaj3T6T6wfZr8okdXaIg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@sec-ant/readable-stream": { + "version": "0.4.1", + "resolved": "https://registry.npmmirror.com/@sec-ant/readable-stream/-/readable-stream-0.4.1.tgz", + "integrity": "sha512-831qok9r2t8AlxLko40y2ebgSDhenenCatLVeW/uBtnHPyhHOvG0C7TvfgecV+wHzIm5KUICgzmVpWS+IMEAeg==", + "dev": true, + "license": "MIT" + }, + "node_modules/@sindresorhus/merge-streams": { + "version": "4.0.0", + "resolved": "https://registry.npmmirror.com/@sindresorhus/merge-streams/-/merge-streams-4.0.0.tgz", + "integrity": "sha512-tlqY9xq5ukxTUZBmoOp+m61cqwQD5pHJtFY3Mn8CA8ps6yghLH/Hw8UPdqg4OLmFW3IFlcXnQNmo/dh8HzXYIQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@tsconfig/node22": { + "version": "22.0.0", + "resolved": "https://registry.npmmirror.com/@tsconfig/node22/-/node22-22.0.0.tgz", + "integrity": "sha512-twLQ77zevtxobBOD4ToAtVmuYrpeYUh3qh+TEp+08IWhpsrIflVHqQ1F1CiPxQGL7doCdBIOOCF+1Tm833faNg==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/estree": { + "version": "1.0.6", + "resolved": "https://registry.npmmirror.com/@types/estree/-/estree-1.0.6.tgz", + "integrity": "sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/lodash": { + "version": "4.17.13", + "resolved": "https://registry.npmmirror.com/@types/lodash/-/lodash-4.17.13.tgz", + "integrity": "sha512-lfx+dftrEZcdBPczf9d0Qv0x+j/rfNCMuC6OcfXmO8gkfeNAY88PgKUbvG56whcN23gc27yenwF6oJZXGFpYxg==", + "license": "MIT" + }, + "node_modules/@types/lodash-es": { + "version": "4.17.12", + "resolved": "https://registry.npmmirror.com/@types/lodash-es/-/lodash-es-4.17.12.tgz", + "integrity": "sha512-0NgftHUcV4v34VhXm8QBSftKVXtbkBG3ViCjs6+eJ5a6y6Mi/jiFGPc1sC7QK+9BFhWrURE3EOggmWaSxL9OzQ==", + "license": "MIT", + "dependencies": { + "@types/lodash": "*" + } + }, + "node_modules/@types/node": { + "version": "22.10.2", + "resolved": "https://registry.npmmirror.com/@types/node/-/node-22.10.2.tgz", + "integrity": "sha512-Xxr6BBRCAOQixvonOye19wnzyDiUtTeqldOOmj3CkeblonbccA12PFwlufvRdrpjXxqnmUaeiU5EOA+7s5diUQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "undici-types": "~6.20.0" + } + }, + "node_modules/@types/web-bluetooth": { + "version": "0.0.16", + "resolved": "https://registry.npmmirror.com/@types/web-bluetooth/-/web-bluetooth-0.0.16.tgz", + "integrity": "sha512-oh8q2Zc32S6gd/j50GowEjKLoOVOwHP/bWVjKJInBwQqdOYMdPrf1oVlelTlyfFK3CKxL1uahMDAr+vy8T7yMQ==", + "license": "MIT" + }, + "node_modules/@vitejs/plugin-vue": { + "version": "5.2.1", + "resolved": "https://registry.npmmirror.com/@vitejs/plugin-vue/-/plugin-vue-5.2.1.tgz", + "integrity": "sha512-cxh314tzaWwOLqVes2gnnCtvBDcM1UMdn+iFR+UjAn411dPT3tOmqrJjbMd7koZpMAmBM/GqeV4n9ge7JSiJJQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^18.0.0 || >=20.0.0" + }, + "peerDependencies": { + "vite": "^5.0.0 || ^6.0.0", + "vue": "^3.2.25" + } + }, + "node_modules/@volar/language-core": { + "version": "2.4.11", + "resolved": "https://registry.npmmirror.com/@volar/language-core/-/language-core-2.4.11.tgz", + "integrity": "sha512-lN2C1+ByfW9/JRPpqScuZt/4OrUUse57GLI6TbLgTIqBVemdl1wNcZ1qYGEo2+Gw8coYLgCy7SuKqn6IrQcQgg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@volar/source-map": "2.4.11" + } + }, + "node_modules/@volar/source-map": { + "version": "2.4.11", + "resolved": "https://registry.npmmirror.com/@volar/source-map/-/source-map-2.4.11.tgz", + "integrity": "sha512-ZQpmafIGvaZMn/8iuvCFGrW3smeqkq/IIh9F1SdSx9aUl0J4Iurzd6/FhmjNO5g2ejF3rT45dKskgXWiofqlZQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/@volar/typescript": { + "version": "2.4.11", + "resolved": "https://registry.npmmirror.com/@volar/typescript/-/typescript-2.4.11.tgz", + "integrity": "sha512-2DT+Tdh88Spp5PyPbqhyoYavYCPDsqbHLFwcUI9K1NlY1YgUJvujGdrqUp0zWxnW7KWNTr3xSpMuv2WnaTKDAw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@volar/language-core": "2.4.11", + "path-browserify": "^1.0.1", + "vscode-uri": "^3.0.8" + } + }, + "node_modules/@vue/babel-helper-vue-transform-on": { + "version": "1.2.5", + "resolved": "https://registry.npmmirror.com/@vue/babel-helper-vue-transform-on/-/babel-helper-vue-transform-on-1.2.5.tgz", + "integrity": "sha512-lOz4t39ZdmU4DJAa2hwPYmKc8EsuGa2U0L9KaZaOJUt0UwQNjNA3AZTq6uEivhOKhhG1Wvy96SvYBoFmCg3uuw==", + "dev": true, + "license": "MIT" + }, + "node_modules/@vue/babel-plugin-jsx": { + "version": "1.2.5", + "resolved": "https://registry.npmmirror.com/@vue/babel-plugin-jsx/-/babel-plugin-jsx-1.2.5.tgz", + "integrity": "sha512-zTrNmOd4939H9KsRIGmmzn3q2zvv1mjxkYZHgqHZgDrXz5B1Q3WyGEjO2f+JrmKghvl1JIRcvo63LgM1kH5zFg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-module-imports": "^7.24.7", + "@babel/helper-plugin-utils": "^7.24.8", + "@babel/plugin-syntax-jsx": "^7.24.7", + "@babel/template": "^7.25.0", + "@babel/traverse": "^7.25.6", + "@babel/types": "^7.25.6", + "@vue/babel-helper-vue-transform-on": "1.2.5", + "@vue/babel-plugin-resolve-type": "1.2.5", + "html-tags": "^3.3.1", + "svg-tags": "^1.0.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + }, + "peerDependenciesMeta": { + "@babel/core": { + "optional": true + } + } + }, + "node_modules/@vue/babel-plugin-resolve-type": { + "version": "1.2.5", + "resolved": "https://registry.npmmirror.com/@vue/babel-plugin-resolve-type/-/babel-plugin-resolve-type-1.2.5.tgz", + "integrity": "sha512-U/ibkQrf5sx0XXRnUZD1mo5F7PkpKyTbfXM3a3rC4YnUz6crHEz9Jg09jzzL6QYlXNto/9CePdOg/c87O4Nlfg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.24.7", + "@babel/helper-module-imports": "^7.24.7", + "@babel/helper-plugin-utils": "^7.24.8", + "@babel/parser": "^7.25.6", + "@vue/compiler-sfc": "^3.5.3" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@vue/compiler-core": { + "version": "3.5.13", + "resolved": "https://registry.npmmirror.com/@vue/compiler-core/-/compiler-core-3.5.13.tgz", + "integrity": "sha512-oOdAkwqUfW1WqpwSYJce06wvt6HljgY3fGeM9NcVA1HaYOij3mZG9Rkysn0OHuyUAGMbEbARIpsG+LPVlBJ5/Q==", + "license": "MIT", + "dependencies": { + "@babel/parser": "^7.25.3", + "@vue/shared": "3.5.13", + "entities": "^4.5.0", + "estree-walker": "^2.0.2", + "source-map-js": "^1.2.0" + } + }, + "node_modules/@vue/compiler-dom": { + "version": "3.5.13", + "resolved": "https://registry.npmmirror.com/@vue/compiler-dom/-/compiler-dom-3.5.13.tgz", + "integrity": "sha512-ZOJ46sMOKUjO3e94wPdCzQ6P1Lx/vhp2RSvfaab88Ajexs0AHeV0uasYhi99WPaogmBlRHNRuly8xV75cNTMDA==", + "license": "MIT", + "dependencies": { + "@vue/compiler-core": "3.5.13", + "@vue/shared": "3.5.13" + } + }, + "node_modules/@vue/compiler-sfc": { + "version": "3.5.13", + "resolved": "https://registry.npmmirror.com/@vue/compiler-sfc/-/compiler-sfc-3.5.13.tgz", + "integrity": "sha512-6VdaljMpD82w6c2749Zhf5T9u5uLBWKnVue6XWxprDobftnletJ8+oel7sexFfM3qIxNmVE7LSFGTpv6obNyaQ==", + "license": "MIT", + "dependencies": { + "@babel/parser": "^7.25.3", + "@vue/compiler-core": "3.5.13", + "@vue/compiler-dom": "3.5.13", + "@vue/compiler-ssr": "3.5.13", + "@vue/shared": "3.5.13", + "estree-walker": "^2.0.2", + "magic-string": "^0.30.11", + "postcss": "^8.4.48", + "source-map-js": "^1.2.0" + } + }, + "node_modules/@vue/compiler-ssr": { + "version": "3.5.13", + "resolved": "https://registry.npmmirror.com/@vue/compiler-ssr/-/compiler-ssr-3.5.13.tgz", + "integrity": "sha512-wMH6vrYHxQl/IybKJagqbquvxpWCuVYpoUJfCqFZwa/JY1GdATAQ+TgVtgrwwMZ0D07QhA99rs/EAAWfvG6KpA==", + "license": "MIT", + "dependencies": { + "@vue/compiler-dom": "3.5.13", + "@vue/shared": "3.5.13" + } + }, + "node_modules/@vue/compiler-vue2": { + "version": "2.7.16", + "resolved": "https://registry.npmmirror.com/@vue/compiler-vue2/-/compiler-vue2-2.7.16.tgz", + "integrity": "sha512-qYC3Psj9S/mfu9uVi5WvNZIzq+xnXMhOwbTFKKDD7b1lhpnn71jXSFdTQ+WsIEk0ONCd7VV2IMm7ONl6tbQ86A==", + "dev": true, + "license": "MIT", + "dependencies": { + "de-indent": "^1.0.2", + "he": "^1.2.0" + } + }, + "node_modules/@vue/devtools-api": { + "version": "6.6.4", + "resolved": "https://registry.npmmirror.com/@vue/devtools-api/-/devtools-api-6.6.4.tgz", + "integrity": "sha512-sGhTPMuXqZ1rVOk32RylztWkfXTRhuS7vgAKv0zjqk8gbsHkJ7xfFf+jbySxt7tWObEJwyKaHMikV/WGDiQm8g==", + "license": "MIT" + }, + "node_modules/@vue/devtools-core": { + "version": "7.6.8", + "resolved": "https://registry.npmmirror.com/@vue/devtools-core/-/devtools-core-7.6.8.tgz", + "integrity": "sha512-8X4roysTwzQ94o7IobjVcOd1aZF5iunikrMrHPI2uUdigZCi2kFTQc7ffYiFiTNaLElCpjOhCnM7bo7aK1yU7A==", + "dev": true, + "license": "MIT", + "dependencies": { + "@vue/devtools-kit": "^7.6.8", + "@vue/devtools-shared": "^7.6.8", + "mitt": "^3.0.1", + "nanoid": "^5.0.9", + "pathe": "^1.1.2", + "vite-hot-client": "^0.2.4" + }, + "peerDependencies": { + "vue": "^3.0.0" + } + }, + "node_modules/@vue/devtools-core/node_modules/nanoid": { + "version": "5.0.9", + "resolved": "https://registry.npmmirror.com/nanoid/-/nanoid-5.0.9.tgz", + "integrity": "sha512-Aooyr6MXU6HpvvWXKoVoXwKMs/KyVakWwg7xQfv5/S/RIgJMy0Ifa45H9qqYy7pTCszrHzP21Uk4PZq2HpEM8Q==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "bin": { + "nanoid": "bin/nanoid.js" + }, + "engines": { + "node": "^18 || >=20" + } + }, + "node_modules/@vue/devtools-kit": { + "version": "7.6.8", + "resolved": "https://registry.npmmirror.com/@vue/devtools-kit/-/devtools-kit-7.6.8.tgz", + "integrity": "sha512-JhJ8M3sPU+v0P2iZBF2DkdmR9L0dnT5RXJabJqX6o8KtFs3tebdvfoXV2Dm3BFuqeECuMJIfF1aCzSt+WQ4wrw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@vue/devtools-shared": "^7.6.8", + "birpc": "^0.2.19", + "hookable": "^5.5.3", + "mitt": "^3.0.1", + "perfect-debounce": "^1.0.0", + "speakingurl": "^14.0.1", + "superjson": "^2.2.1" + } + }, + "node_modules/@vue/devtools-shared": { + "version": "7.6.8", + "resolved": "https://registry.npmmirror.com/@vue/devtools-shared/-/devtools-shared-7.6.8.tgz", + "integrity": "sha512-9MBPO5Z3X1nYGFqTJyohl6Gmf/J7UNN1oicHdyzBVZP4jnhZ4c20MgtaHDIzWmHDHCMYVS5bwKxT3jxh7gOOKA==", + "dev": true, + "license": "MIT", + "dependencies": { + "rfdc": "^1.4.1" + } + }, + "node_modules/@vue/language-core": { + "version": "2.2.0", + "resolved": "https://registry.npmmirror.com/@vue/language-core/-/language-core-2.2.0.tgz", + "integrity": "sha512-O1ZZFaaBGkKbsRfnVH1ifOK1/1BUkyK+3SQsfnh6PmMmD4qJcTU8godCeA96jjDRTL6zgnK7YzCHfaUlH2r0Mw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@volar/language-core": "~2.4.11", + "@vue/compiler-dom": "^3.5.0", + "@vue/compiler-vue2": "^2.7.16", + "@vue/shared": "^3.5.0", + "alien-signals": "^0.4.9", + "minimatch": "^9.0.3", + "muggle-string": "^0.4.1", + "path-browserify": "^1.0.1" + }, + "peerDependencies": { + "typescript": "*" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@vue/reactivity": { + "version": "3.5.13", + "resolved": "https://registry.npmmirror.com/@vue/reactivity/-/reactivity-3.5.13.tgz", + "integrity": "sha512-NaCwtw8o48B9I6L1zl2p41OHo/2Z4wqYGGIK1Khu5T7yxrn+ATOixn/Udn2m+6kZKB/J7cuT9DbWWhRxqixACg==", + "license": "MIT", + "dependencies": { + "@vue/shared": "3.5.13" + } + }, + "node_modules/@vue/runtime-core": { + "version": "3.5.13", + "resolved": "https://registry.npmmirror.com/@vue/runtime-core/-/runtime-core-3.5.13.tgz", + "integrity": "sha512-Fj4YRQ3Az0WTZw1sFe+QDb0aXCerigEpw418pw1HBUKFtnQHWzwojaukAs2X/c9DQz4MQ4bsXTGlcpGxU/RCIw==", + "license": "MIT", + "dependencies": { + "@vue/reactivity": "3.5.13", + "@vue/shared": "3.5.13" + } + }, + "node_modules/@vue/runtime-dom": { + "version": "3.5.13", + "resolved": "https://registry.npmmirror.com/@vue/runtime-dom/-/runtime-dom-3.5.13.tgz", + "integrity": "sha512-dLaj94s93NYLqjLiyFzVs9X6dWhTdAlEAciC3Moq7gzAc13VJUdCnjjRurNM6uTLFATRHexHCTu/Xp3eW6yoog==", + "license": "MIT", + "dependencies": { + "@vue/reactivity": "3.5.13", + "@vue/runtime-core": "3.5.13", + "@vue/shared": "3.5.13", + "csstype": "^3.1.3" + } + }, + "node_modules/@vue/server-renderer": { + "version": "3.5.13", + "resolved": "https://registry.npmmirror.com/@vue/server-renderer/-/server-renderer-3.5.13.tgz", + "integrity": "sha512-wAi4IRJV/2SAW3htkTlB+dHeRmpTiVIK1OGLWV1yeStVSebSQQOwGwIq0D3ZIoBj2C2qpgz5+vX9iEBkTdk5YA==", + "license": "MIT", + "dependencies": { + "@vue/compiler-ssr": "3.5.13", + "@vue/shared": "3.5.13" + }, + "peerDependencies": { + "vue": "3.5.13" + } + }, + "node_modules/@vue/shared": { + "version": "3.5.13", + "resolved": "https://registry.npmmirror.com/@vue/shared/-/shared-3.5.13.tgz", + "integrity": "sha512-/hnE/qP5ZoGpol0a5mDi45bOd7t3tjYJBjsgCsivow7D48cJeV5l05RD82lPqi7gRiphZM37rnhW1l6ZoCNNnQ==", + "license": "MIT" + }, + "node_modules/@vue/tsconfig": { + "version": "0.7.0", + "resolved": "https://registry.npmmirror.com/@vue/tsconfig/-/tsconfig-0.7.0.tgz", + "integrity": "sha512-ku2uNz5MaZ9IerPPUyOHzyjhXoX2kVJaVf7hL315DC17vS6IiZRmmCPfggNbU16QTvM80+uYYy3eYJB59WCtvg==", + "dev": true, + "license": "MIT", + "peerDependencies": { + "typescript": "5.x", + "vue": "^3.4.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + }, + "vue": { + "optional": true + } + } + }, + "node_modules/@vueuse/core": { + "version": "9.13.0", + "resolved": "https://registry.npmmirror.com/@vueuse/core/-/core-9.13.0.tgz", + "integrity": "sha512-pujnclbeHWxxPRqXWmdkKV5OX4Wk4YeK7wusHqRwU0Q7EFusHoqNA/aPhB6KCh9hEqJkLAJo7bb0Lh9b+OIVzw==", + "license": "MIT", + "dependencies": { + "@types/web-bluetooth": "^0.0.16", + "@vueuse/metadata": "9.13.0", + "@vueuse/shared": "9.13.0", + "vue-demi": "*" + }, + "funding": { + "url": "https://github.com/sponsors/antfu" + } + }, + "node_modules/@vueuse/metadata": { + "version": "9.13.0", + "resolved": "https://registry.npmmirror.com/@vueuse/metadata/-/metadata-9.13.0.tgz", + "integrity": "sha512-gdU7TKNAUVlXXLbaF+ZCfte8BjRJQWPCa2J55+7/h+yDtzw3vOoGQDRXzI6pyKyo6bXFT5/QoPE4hAknExjRLQ==", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/antfu" + } + }, + "node_modules/@vueuse/shared": { + "version": "9.13.0", + "resolved": "https://registry.npmmirror.com/@vueuse/shared/-/shared-9.13.0.tgz", + "integrity": "sha512-UrnhU+Cnufu4S6JLCPZnkWh0WwZGUp72ktOF2DFptMlOs3TOdVv8xJN53zhHGARmVOsz5KqOls09+J1NR6sBKw==", + "license": "MIT", + "dependencies": { + "vue-demi": "*" + }, + "funding": { + "url": "https://github.com/sponsors/antfu" + } + }, + "node_modules/alien-signals": { + "version": "0.4.11", + "resolved": "https://registry.npmmirror.com/alien-signals/-/alien-signals-0.4.11.tgz", + "integrity": "sha512-79GUbcQM5K2zb+HyUMODTgJdVjZWwybDNQRduqP9ks7XZvJylm9uWesOjVcu6/veWsa+XNGVE4xVQ8+RGu8HaA==", + "dev": true, + "license": "MIT" + }, + "node_modules/ansi-styles": { + "version": "6.2.1", + "resolved": "https://registry.npmmirror.com/ansi-styles/-/ansi-styles-6.2.1.tgz", + "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/async-validator": { + "version": "4.2.5", + "resolved": "https://registry.npmmirror.com/async-validator/-/async-validator-4.2.5.tgz", + "integrity": "sha512-7HhHjtERjqlNbZtqNqy2rckN/SpOOlmDliet+lP7k+eKZEjPk3DgyeU9lIXLdeLz0uBbbVp+9Qdow9wJWgwwfg==", + "license": "MIT" + }, + "node_modules/asynckit": { + "version": "0.4.0", + "resolved": "https://registry.npmmirror.com/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==", + "license": "MIT" + }, + "node_modules/axios": { + "version": "1.7.9", + "resolved": "https://registry.npmmirror.com/axios/-/axios-1.7.9.tgz", + "integrity": "sha512-LhLcE7Hbiryz8oMDdDptSrWowmB4Bl6RCt6sIJKpRB4XtVf0iEgewX3au/pJqm+Py1kCASkb/FFKjxQaLtxJvw==", + "license": "MIT", + "dependencies": { + "follow-redirects": "^1.15.6", + "form-data": "^4.0.0", + "proxy-from-env": "^1.1.0" + } + }, + "node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmmirror.com/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "dev": true, + "license": "MIT" + }, + "node_modules/birpc": { + "version": "0.2.19", + "resolved": "https://registry.npmmirror.com/birpc/-/birpc-0.2.19.tgz", + "integrity": "sha512-5WeXXAvTmitV1RqJFppT5QtUiz2p1mRSYU000Jkft5ZUCLJIk4uQriYNO50HknxKwM6jd8utNc66K1qGIwwWBQ==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/antfu" + } + }, + "node_modules/brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmmirror.com/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/browserslist": { + "version": "4.24.3", + "resolved": "https://registry.npmmirror.com/browserslist/-/browserslist-4.24.3.tgz", + "integrity": "sha512-1CPmv8iobE2fyRMV97dAcMVegvvWKxmq94hkLiAkUGwKVTyDLw33K+ZxiFrREKmmps4rIw6grcCFCnTMSZ/YiA==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "caniuse-lite": "^1.0.30001688", + "electron-to-chromium": "^1.5.73", + "node-releases": "^2.0.19", + "update-browserslist-db": "^1.1.1" + }, + "bin": { + "browserslist": "cli.js" + }, + "engines": { + "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" + } + }, + "node_modules/bundle-name": { + "version": "4.1.0", + "resolved": "https://registry.npmmirror.com/bundle-name/-/bundle-name-4.1.0.tgz", + "integrity": "sha512-tjwM5exMg6BGRI+kNmTntNsvdZS1X8BFYS6tnJ2hdH0kVxM6/eVZ2xy+FqStSWvYmtfFMDLIxurorHwDKfDz5Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "run-applescript": "^7.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/caniuse-lite": { + "version": "1.0.30001690", + "resolved": "https://registry.npmmirror.com/caniuse-lite/-/caniuse-lite-1.0.30001690.tgz", + "integrity": "sha512-5ExiE3qQN6oF8Clf8ifIDcMRCRE/dMGcETG/XGMD8/XiXm6HXQgQTh1yZYLXXpSOsEUlJm1Xr7kGULZTuGtP/w==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/caniuse-lite" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "CC-BY-4.0" + }, + "node_modules/combined-stream": { + "version": "1.0.8", + "resolved": "https://registry.npmmirror.com/combined-stream/-/combined-stream-1.0.8.tgz", + "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", + "license": "MIT", + "dependencies": { + "delayed-stream": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/convert-source-map": { + "version": "2.0.0", + "resolved": "https://registry.npmmirror.com/convert-source-map/-/convert-source-map-2.0.0.tgz", + "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", + "dev": true, + "license": "MIT" + }, + "node_modules/copy-anything": { + "version": "3.0.5", + "resolved": "https://registry.npmmirror.com/copy-anything/-/copy-anything-3.0.5.tgz", + "integrity": "sha512-yCEafptTtb4bk7GLEQoM8KVJpxAfdBJYaXyzQEgQQQgYrZiDp8SJmGKlYza6CYjEDNstAdNdKA3UuoULlEbS6w==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-what": "^4.1.8" + }, + "engines": { + "node": ">=12.13" + }, + "funding": { + "url": "https://github.com/sponsors/mesqueeb" + } + }, + "node_modules/cross-spawn": { + "version": "7.0.6", + "resolved": "https://registry.npmmirror.com/cross-spawn/-/cross-spawn-7.0.6.tgz", + "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==", + "dev": true, + "license": "MIT", + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/cross-spawn/node_modules/isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmmirror.com/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", + "dev": true, + "license": "ISC" + }, + "node_modules/cross-spawn/node_modules/which": { + "version": "2.0.2", + "resolved": "https://registry.npmmirror.com/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "license": "ISC", + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/csstype": { + "version": "3.1.3", + "resolved": "https://registry.npmmirror.com/csstype/-/csstype-3.1.3.tgz", + "integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==", + "license": "MIT" + }, + "node_modules/dayjs": { + "version": "1.11.13", + "resolved": "https://registry.npmmirror.com/dayjs/-/dayjs-1.11.13.tgz", + "integrity": "sha512-oaMBel6gjolK862uaPQOVTA7q3TZhuSvuMQAAglQDOWYO9A91IrAOUJEyKVlqJlHE0vq5p5UXxzdPfMH/x6xNg==", + "license": "MIT" + }, + "node_modules/de-indent": { + "version": "1.0.2", + "resolved": "https://registry.npmmirror.com/de-indent/-/de-indent-1.0.2.tgz", + "integrity": "sha512-e/1zu3xH5MQryN2zdVaF0OrdNLUbvWxzMbi+iNA6Bky7l1RoP8a2fIbRocyHclXt/arDrrR6lL3TqFD9pMQTsg==", + "dev": true, + "license": "MIT" + }, + "node_modules/debug": { + "version": "4.4.0", + "resolved": "https://registry.npmmirror.com/debug/-/debug-4.4.0.tgz", + "integrity": "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/default-browser": { + "version": "5.2.1", + "resolved": "https://registry.npmmirror.com/default-browser/-/default-browser-5.2.1.tgz", + "integrity": "sha512-WY/3TUME0x3KPYdRRxEJJvXRHV4PyPoUsxtZa78lwItwRQRHhd2U9xOscaT/YTf8uCXIAjeJOFBVEh/7FtD8Xg==", + "dev": true, + "license": "MIT", + "dependencies": { + "bundle-name": "^4.1.0", + "default-browser-id": "^5.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/default-browser-id": { + "version": "5.0.0", + "resolved": "https://registry.npmmirror.com/default-browser-id/-/default-browser-id-5.0.0.tgz", + "integrity": "sha512-A6p/pu/6fyBcA1TRz/GqWYPViplrftcW2gZC9q79ngNCKAeR/X3gcEdXQHl4KNXV+3wgIJ1CPkJQ3IHM6lcsyA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/define-lazy-prop": { + "version": "3.0.0", + "resolved": "https://registry.npmmirror.com/define-lazy-prop/-/define-lazy-prop-3.0.0.tgz", + "integrity": "sha512-N+MeXYoqr3pOgn8xfyRPREN7gHakLYjhsHhWGT3fWAiL4IkAt0iDw14QiiEm2bE30c5XX5q0FtAA3CK5f9/BUg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/delayed-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmmirror.com/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", + "license": "MIT", + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/echarts": { + "version": "5.6.0", + "resolved": "https://registry.npmmirror.com/echarts/-/echarts-5.6.0.tgz", + "integrity": "sha512-oTbVTsXfKuEhxftHqL5xprgLoc0k7uScAwtryCgWF6hPYFLRwOUHiFmHGCBKP5NPFNkDVopOieyUqYGH8Fa3kA==", + "license": "Apache-2.0", + "dependencies": { + "tslib": "2.3.0", + "zrender": "5.6.1" + } + }, + "node_modules/electron-to-chromium": { + "version": "1.5.76", + "resolved": "https://registry.npmmirror.com/electron-to-chromium/-/electron-to-chromium-1.5.76.tgz", + "integrity": "sha512-CjVQyG7n7Sr+eBXE86HIulnL5N8xZY1sgmOPGuq/F0Rr0FJq63lg0kEtOIDfZBk44FnDLf6FUJ+dsJcuiUDdDQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/element-plus": { + "version": "2.9.1", + "resolved": "https://registry.npmmirror.com/element-plus/-/element-plus-2.9.1.tgz", + "integrity": "sha512-9Agqf/jt4Ugk7EZ6C5LME71sgkvauPCsnvJN12Xid2XVobjufxMGpRE4L7pS4luJMOmFAH3J0NgYEGZT5r+NDg==", + "license": "MIT", + "dependencies": { + "@ctrl/tinycolor": "^3.4.1", + "@element-plus/icons-vue": "^2.3.1", + "@floating-ui/dom": "^1.0.1", + "@popperjs/core": "npm:@sxzz/popperjs-es@^2.11.7", + "@types/lodash": "^4.14.182", + "@types/lodash-es": "^4.17.6", + "@vueuse/core": "^9.1.0", + "async-validator": "^4.2.5", + "dayjs": "^1.11.13", + "escape-html": "^1.0.3", + "lodash": "^4.17.21", + "lodash-es": "^4.17.21", + "lodash-unified": "^1.0.2", + "memoize-one": "^6.0.0", + "normalize-wheel-es": "^1.2.0" + }, + "peerDependencies": { + "vue": "^3.2.0" + } + }, + "node_modules/entities": { + "version": "4.5.0", + "resolved": "https://registry.npmmirror.com/entities/-/entities-4.5.0.tgz", + "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==", + "license": "BSD-2-Clause", + "engines": { + "node": ">=0.12" + }, + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, + "node_modules/error-stack-parser-es": { + "version": "0.1.5", + "resolved": "https://registry.npmmirror.com/error-stack-parser-es/-/error-stack-parser-es-0.1.5.tgz", + "integrity": "sha512-xHku1X40RO+fO8yJ8Wh2f2rZWVjqyhb1zgq1yZ8aZRQkv6OOKhKWRUaht3eSCUbAOBaKIgM+ykwFLE+QUxgGeg==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/antfu" + } + }, + "node_modules/esbuild": { + "version": "0.24.2", + "resolved": "https://registry.npmmirror.com/esbuild/-/esbuild-0.24.2.tgz", + "integrity": "sha512-+9egpBW8I3CD5XPe0n6BfT5fxLzxrlDzqydF3aviG+9ni1lDC/OvMHcxqEFV0+LANZG5R1bFMWfUrjVsdwxJvA==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=18" + }, + "optionalDependencies": { + "@esbuild/aix-ppc64": "0.24.2", + "@esbuild/android-arm": "0.24.2", + "@esbuild/android-arm64": "0.24.2", + "@esbuild/android-x64": "0.24.2", + "@esbuild/darwin-arm64": "0.24.2", + "@esbuild/darwin-x64": "0.24.2", + "@esbuild/freebsd-arm64": "0.24.2", + "@esbuild/freebsd-x64": "0.24.2", + "@esbuild/linux-arm": "0.24.2", + "@esbuild/linux-arm64": "0.24.2", + "@esbuild/linux-ia32": "0.24.2", + "@esbuild/linux-loong64": "0.24.2", + "@esbuild/linux-mips64el": "0.24.2", + "@esbuild/linux-ppc64": "0.24.2", + "@esbuild/linux-riscv64": "0.24.2", + "@esbuild/linux-s390x": "0.24.2", + "@esbuild/linux-x64": "0.24.2", + "@esbuild/netbsd-arm64": "0.24.2", + "@esbuild/netbsd-x64": "0.24.2", + "@esbuild/openbsd-arm64": "0.24.2", + "@esbuild/openbsd-x64": "0.24.2", + "@esbuild/sunos-x64": "0.24.2", + "@esbuild/win32-arm64": "0.24.2", + "@esbuild/win32-ia32": "0.24.2", + "@esbuild/win32-x64": "0.24.2" + } + }, + "node_modules/escalade": { + "version": "3.2.0", + "resolved": "https://registry.npmmirror.com/escalade/-/escalade-3.2.0.tgz", + "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/escape-html": { + "version": "1.0.3", + "resolved": "https://registry.npmmirror.com/escape-html/-/escape-html-1.0.3.tgz", + "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==", + "license": "MIT" + }, + "node_modules/estree-walker": { + "version": "2.0.2", + "resolved": "https://registry.npmmirror.com/estree-walker/-/estree-walker-2.0.2.tgz", + "integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==", + "license": "MIT" + }, + "node_modules/execa": { + "version": "9.5.2", + "resolved": "https://registry.npmmirror.com/execa/-/execa-9.5.2.tgz", + "integrity": "sha512-EHlpxMCpHWSAh1dgS6bVeoLAXGnJNdR93aabr4QCGbzOM73o5XmRfM/e5FUqsw3aagP8S8XEWUWFAxnRBnAF0Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@sindresorhus/merge-streams": "^4.0.0", + "cross-spawn": "^7.0.3", + "figures": "^6.1.0", + "get-stream": "^9.0.0", + "human-signals": "^8.0.0", + "is-plain-obj": "^4.1.0", + "is-stream": "^4.0.1", + "npm-run-path": "^6.0.0", + "pretty-ms": "^9.0.0", + "signal-exit": "^4.1.0", + "strip-final-newline": "^4.0.0", + "yoctocolors": "^2.0.0" + }, + "engines": { + "node": "^18.19.0 || >=20.5.0" + }, + "funding": { + "url": "https://github.com/sindresorhus/execa?sponsor=1" + } + }, + "node_modules/figures": { + "version": "6.1.0", + "resolved": "https://registry.npmmirror.com/figures/-/figures-6.1.0.tgz", + "integrity": "sha512-d+l3qxjSesT4V7v2fh+QnmFnUWv9lSpjarhShNTgBOfA0ttejbQUAlHLitbjkoRiDulW0OPoQPYIGhIC8ohejg==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-unicode-supported": "^2.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/follow-redirects": { + "version": "1.15.9", + "resolved": "https://registry.npmmirror.com/follow-redirects/-/follow-redirects-1.15.9.tgz", + "integrity": "sha512-gew4GsXizNgdoRyqmyfMHyAmXsZDk6mHkSxZFCzW9gwlbtOW44CDtYavM+y+72qD/Vq2l550kMF52DT8fOLJqQ==", + "funding": [ + { + "type": "individual", + "url": "https://github.com/sponsors/RubenVerborgh" + } + ], + "license": "MIT", + "engines": { + "node": ">=4.0" + }, + "peerDependenciesMeta": { + "debug": { + "optional": true + } + } + }, + "node_modules/form-data": { + "version": "4.0.1", + "resolved": "https://registry.npmmirror.com/form-data/-/form-data-4.0.1.tgz", + "integrity": "sha512-tzN8e4TX8+kkxGPK8D5u0FNmjPUjw3lwC9lSLxxoB/+GtsJG91CO8bSWy73APlgAZzZbXEYZJuxjkHH2w+Ezhw==", + "license": "MIT", + "dependencies": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.8", + "mime-types": "^2.1.12" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/fs-extra": { + "version": "11.2.0", + "resolved": "https://registry.npmmirror.com/fs-extra/-/fs-extra-11.2.0.tgz", + "integrity": "sha512-PmDi3uwK5nFuXh7XDTlVnS17xJS7vW36is2+w3xcv8SVxiB4NyATf4ctkVY5bkSjX0Y4nbvZCq1/EjtEyr9ktw==", + "dev": true, + "license": "MIT", + "dependencies": { + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + }, + "engines": { + "node": ">=14.14" + } + }, + "node_modules/fsevents": { + "version": "2.3.3", + "resolved": "https://registry.npmmirror.com/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "node_modules/gensync": { + "version": "1.0.0-beta.2", + "resolved": "https://registry.npmmirror.com/gensync/-/gensync-1.0.0-beta.2.tgz", + "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/get-stream": { + "version": "9.0.1", + "resolved": "https://registry.npmmirror.com/get-stream/-/get-stream-9.0.1.tgz", + "integrity": "sha512-kVCxPF3vQM/N0B1PmoqVUqgHP+EeVjmZSQn+1oCRPxd2P21P2F19lIgbR3HBosbB1PUhOAoctJnfEn2GbN2eZA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@sec-ant/readable-stream": "^0.4.1", + "is-stream": "^4.0.1" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/globals": { + "version": "11.12.0", + "resolved": "https://registry.npmmirror.com/globals/-/globals-11.12.0.tgz", + "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/graceful-fs": { + "version": "4.2.11", + "resolved": "https://registry.npmmirror.com/graceful-fs/-/graceful-fs-4.2.11.tgz", + "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/he": { + "version": "1.2.0", + "resolved": "https://registry.npmmirror.com/he/-/he-1.2.0.tgz", + "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==", + "dev": true, + "license": "MIT", + "bin": { + "he": "bin/he" + } + }, + "node_modules/hookable": { + "version": "5.5.3", + "resolved": "https://registry.npmmirror.com/hookable/-/hookable-5.5.3.tgz", + "integrity": "sha512-Yc+BQe8SvoXH1643Qez1zqLRmbA5rCL+sSmk6TVos0LWVfNIB7PGncdlId77WzLGSIB5KaWgTaNTs2lNVEI6VQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/html-tags": { + "version": "3.3.1", + "resolved": "https://registry.npmmirror.com/html-tags/-/html-tags-3.3.1.tgz", + "integrity": "sha512-ztqyC3kLto0e9WbNp0aeP+M3kTt+nbaIveGmUxAtZa+8iFgKLUOD4YKM5j+f3QD89bra7UeumolZHKuOXnTmeQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/human-signals": { + "version": "8.0.0", + "resolved": "https://registry.npmmirror.com/human-signals/-/human-signals-8.0.0.tgz", + "integrity": "sha512-/1/GPCpDUCCYwlERiYjxoczfP0zfvZMU/OWgQPMya9AbAE24vseigFdhAMObpc8Q4lc/kjutPfUddDYyAmejnA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=18.18.0" + } + }, + "node_modules/is-docker": { + "version": "3.0.0", + "resolved": "https://registry.npmmirror.com/is-docker/-/is-docker-3.0.0.tgz", + "integrity": "sha512-eljcgEDlEns/7AXFosB5K/2nCM4P7FQPkGc/DWLy5rmFEWvZayGrik1d9/QIY5nJ4f9YsVvBkA6kJpHn9rISdQ==", + "dev": true, + "license": "MIT", + "bin": { + "is-docker": "cli.js" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-inside-container": { + "version": "1.0.0", + "resolved": "https://registry.npmmirror.com/is-inside-container/-/is-inside-container-1.0.0.tgz", + "integrity": "sha512-KIYLCCJghfHZxqjYBE7rEy0OBuTd5xCHS7tHVgvCLkx7StIoaxwNW3hCALgEUjFfeRk+MG/Qxmp/vtETEF3tRA==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-docker": "^3.0.0" + }, + "bin": { + "is-inside-container": "cli.js" + }, + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-plain-obj": { + "version": "4.1.0", + "resolved": "https://registry.npmmirror.com/is-plain-obj/-/is-plain-obj-4.1.0.tgz", + "integrity": "sha512-+Pgi+vMuUNkJyExiMBt5IlFoMyKnr5zhJ4Uspz58WOhBF5QoIZkFyNHIbBAtHwzVAgk5RtndVNsDRN61/mmDqg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-stream": { + "version": "4.0.1", + "resolved": "https://registry.npmmirror.com/is-stream/-/is-stream-4.0.1.tgz", + "integrity": "sha512-Dnz92NInDqYckGEUJv689RbRiTSEHCQ7wOVeALbkOz999YpqT46yMRIGtSNl2iCL1waAZSx40+h59NV/EwzV/A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-unicode-supported": { + "version": "2.1.0", + "resolved": "https://registry.npmmirror.com/is-unicode-supported/-/is-unicode-supported-2.1.0.tgz", + "integrity": "sha512-mE00Gnza5EEB3Ds0HfMyllZzbBrmLOX3vfWoj9A9PEnTfratQ/BcaJOuMhnkhjXvb2+FkY3VuHqtAGpTPmglFQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-what": { + "version": "4.1.16", + "resolved": "https://registry.npmmirror.com/is-what/-/is-what-4.1.16.tgz", + "integrity": "sha512-ZhMwEosbFJkA0YhFnNDgTM4ZxDRsS6HqTo7qsZM08fehyRYIYa0yHu5R6mgo1n/8MgaPBXiPimPD77baVFYg+A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12.13" + }, + "funding": { + "url": "https://github.com/sponsors/mesqueeb" + } + }, + "node_modules/is-wsl": { + "version": "3.1.0", + "resolved": "https://registry.npmmirror.com/is-wsl/-/is-wsl-3.1.0.tgz", + "integrity": "sha512-UcVfVfaK4Sc4m7X3dUSoHoozQGBEFeDC+zVo06t98xe8CzHSZZBekNXH+tu0NalHolcJ/QAGqS46Hef7QXBIMw==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-inside-container": "^1.0.0" + }, + "engines": { + "node": ">=16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/isexe": { + "version": "3.1.1", + "resolved": "https://registry.npmmirror.com/isexe/-/isexe-3.1.1.tgz", + "integrity": "sha512-LpB/54B+/2J5hqQ7imZHfdU31OlgQqx7ZicVlkm9kzg9/w8GKLEcFfJl/t7DCEDueOyBAD6zCCwTO6Fzs0NoEQ==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=16" + } + }, + "node_modules/js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmmirror.com/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/jsesc": { + "version": "3.1.0", + "resolved": "https://registry.npmmirror.com/jsesc/-/jsesc-3.1.0.tgz", + "integrity": "sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==", + "dev": true, + "license": "MIT", + "bin": { + "jsesc": "bin/jsesc" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/json-parse-even-better-errors": { + "version": "4.0.0", + "resolved": "https://registry.npmmirror.com/json-parse-even-better-errors/-/json-parse-even-better-errors-4.0.0.tgz", + "integrity": "sha512-lR4MXjGNgkJc7tkQ97kb2nuEMnNCyU//XYVH0MKTGcXEiSudQ5MKGKen3C5QubYy0vmq+JGitUg92uuywGEwIA==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/json5": { + "version": "2.2.3", + "resolved": "https://registry.npmmirror.com/json5/-/json5-2.2.3.tgz", + "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", + "dev": true, + "license": "MIT", + "bin": { + "json5": "lib/cli.js" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/jsonfile": { + "version": "6.1.0", + "resolved": "https://registry.npmmirror.com/jsonfile/-/jsonfile-6.1.0.tgz", + "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "universalify": "^2.0.0" + }, + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } + }, + "node_modules/kolorist": { + "version": "1.8.0", + "resolved": "https://registry.npmmirror.com/kolorist/-/kolorist-1.8.0.tgz", + "integrity": "sha512-Y+60/zizpJ3HRH8DCss+q95yr6145JXZo46OTpFvDZWLfRCE4qChOyk1b26nMaNpfHHgxagk9dXT5OP0Tfe+dQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/lodash": { + "version": "4.17.21", + "resolved": "https://registry.npmmirror.com/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", + "license": "MIT" + }, + "node_modules/lodash-es": { + "version": "4.17.21", + "resolved": "https://registry.npmmirror.com/lodash-es/-/lodash-es-4.17.21.tgz", + "integrity": "sha512-mKnC+QJ9pWVzv+C4/U3rRsHapFfHvQFoFB92e52xeyGMcX6/OlIl78je1u8vePzYZSkkogMPJ2yjxxsb89cxyw==", + "license": "MIT" + }, + "node_modules/lodash-unified": { + "version": "1.0.3", + "resolved": "https://registry.npmmirror.com/lodash-unified/-/lodash-unified-1.0.3.tgz", + "integrity": "sha512-WK9qSozxXOD7ZJQlpSqOT+om2ZfcT4yO+03FuzAHD0wF6S0l0090LRPDx3vhTTLZ8cFKpBn+IOcVXK6qOcIlfQ==", + "license": "MIT", + "peerDependencies": { + "@types/lodash-es": "*", + "lodash": "*", + "lodash-es": "*" + } + }, + "node_modules/lru-cache": { + "version": "5.1.1", + "resolved": "https://registry.npmmirror.com/lru-cache/-/lru-cache-5.1.1.tgz", + "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", + "dev": true, + "license": "ISC", + "dependencies": { + "yallist": "^3.0.2" + } + }, + "node_modules/magic-string": { + "version": "0.30.17", + "resolved": "https://registry.npmmirror.com/magic-string/-/magic-string-0.30.17.tgz", + "integrity": "sha512-sNPKHvyjVf7gyjwS4xGTaW/mCnF8wnjtifKBEhxfZ7E/S8tQ0rssrwGNn6q8JH/ohItJfSQp9mBtQYuTlH5QnA==", + "license": "MIT", + "dependencies": { + "@jridgewell/sourcemap-codec": "^1.5.0" + } + }, + "node_modules/memoize-one": { + "version": "6.0.0", + "resolved": "https://registry.npmmirror.com/memoize-one/-/memoize-one-6.0.0.tgz", + "integrity": "sha512-rkpe71W0N0c0Xz6QD0eJETuWAJGnJ9afsl1srmwPrI+yBCkge5EycXXbYRyvL29zZVUWQCY7InPRCv3GDXuZNw==", + "license": "MIT" + }, + "node_modules/memorystream": { + "version": "0.3.1", + "resolved": "https://registry.npmmirror.com/memorystream/-/memorystream-0.3.1.tgz", + "integrity": "sha512-S3UwM3yj5mtUSEfP41UZmt/0SCoVYUcU1rkXv+BQ5Ig8ndL4sPoJNBUJERafdPb5jjHJGuMgytgKvKIf58XNBw==", + "dev": true, + "engines": { + "node": ">= 0.10.0" + } + }, + "node_modules/mime-db": { + "version": "1.52.0", + "resolved": "https://registry.npmmirror.com/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mime-types": { + "version": "2.1.35", + "resolved": "https://registry.npmmirror.com/mime-types/-/mime-types-2.1.35.tgz", + "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", + "license": "MIT", + "dependencies": { + "mime-db": "1.52.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/minimatch": { + "version": "9.0.5", + "resolved": "https://registry.npmmirror.com/minimatch/-/minimatch-9.0.5.tgz", + "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/mitt": { + "version": "3.0.1", + "resolved": "https://registry.npmmirror.com/mitt/-/mitt-3.0.1.tgz", + "integrity": "sha512-vKivATfr97l2/QBCYAkXYDbrIWPM2IIKEl7YPhjCvKlG3kE2gm+uBo6nEXK3M5/Ffh/FLpKExzOQ3JJoJGFKBw==", + "dev": true, + "license": "MIT" + }, + "node_modules/mrmime": { + "version": "2.0.0", + "resolved": "https://registry.npmmirror.com/mrmime/-/mrmime-2.0.0.tgz", + "integrity": "sha512-eu38+hdgojoyq63s+yTpN4XMBdt5l8HhMhc4VKLO9KM5caLIBvUm4thi7fFaxyTmCKeNnXZ5pAlBwCUnhA09uw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + } + }, + "node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmmirror.com/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "dev": true, + "license": "MIT" + }, + "node_modules/muggle-string": { + "version": "0.4.1", + "resolved": "https://registry.npmmirror.com/muggle-string/-/muggle-string-0.4.1.tgz", + "integrity": "sha512-VNTrAak/KhO2i8dqqnqnAHOa3cYBwXEZe9h+D5h/1ZqFSTEFHdM65lR7RoIqq3tBBYavsOXV84NoHXZ0AkPyqQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/nanoid": { + "version": "3.3.8", + "resolved": "https://registry.npmmirror.com/nanoid/-/nanoid-3.3.8.tgz", + "integrity": "sha512-WNLf5Sd8oZxOm+TzppcYk8gVOgP+l58xNy58D0nbUnOxOWRWvlcCV4kUF7ltmI6PsrLl/BgKEyS4mqsGChFN0w==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "bin": { + "nanoid": "bin/nanoid.cjs" + }, + "engines": { + "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" + } + }, + "node_modules/node-releases": { + "version": "2.0.19", + "resolved": "https://registry.npmmirror.com/node-releases/-/node-releases-2.0.19.tgz", + "integrity": "sha512-xxOWJsBKtzAq7DY0J+DTzuz58K8e7sJbdgwkbMWQe8UYB6ekmsQ45q0M/tJDsGaZmbC+l7n57UV8Hl5tHxO9uw==", + "dev": true, + "license": "MIT" + }, + "node_modules/normalize-wheel-es": { + "version": "1.2.0", + "resolved": "https://registry.npmmirror.com/normalize-wheel-es/-/normalize-wheel-es-1.2.0.tgz", + "integrity": "sha512-Wj7+EJQ8mSuXr2iWfnujrimU35R2W4FAErEyTmJoJ7ucwTn2hOUSsRehMb5RSYkxXGTM7Y9QpvPmp++w5ftoJw==", + "license": "BSD-3-Clause" + }, + "node_modules/npm-normalize-package-bin": { + "version": "4.0.0", + "resolved": "https://registry.npmmirror.com/npm-normalize-package-bin/-/npm-normalize-package-bin-4.0.0.tgz", + "integrity": "sha512-TZKxPvItzai9kN9H/TkmCtx/ZN/hvr3vUycjlfmH0ootY9yFBzNOpiXAdIn1Iteqsvk4lQn6B5PTrt+n6h8k/w==", + "dev": true, + "license": "ISC", + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/npm-run-all2": { + "version": "7.0.2", + "resolved": "https://registry.npmmirror.com/npm-run-all2/-/npm-run-all2-7.0.2.tgz", + "integrity": "sha512-7tXR+r9hzRNOPNTvXegM+QzCuMjzUIIq66VDunL6j60O4RrExx32XUhlrS7UK4VcdGw5/Wxzb3kfNcFix9JKDA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^6.2.1", + "cross-spawn": "^7.0.6", + "memorystream": "^0.3.1", + "minimatch": "^9.0.0", + "pidtree": "^0.6.0", + "read-package-json-fast": "^4.0.0", + "shell-quote": "^1.7.3", + "which": "^5.0.0" + }, + "bin": { + "npm-run-all": "bin/npm-run-all/index.js", + "npm-run-all2": "bin/npm-run-all/index.js", + "run-p": "bin/run-p/index.js", + "run-s": "bin/run-s/index.js" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0", + "npm": ">= 9" + } + }, + "node_modules/npm-run-path": { + "version": "6.0.0", + "resolved": "https://registry.npmmirror.com/npm-run-path/-/npm-run-path-6.0.0.tgz", + "integrity": "sha512-9qny7Z9DsQU8Ou39ERsPU4OZQlSTP47ShQzuKZ6PRXpYLtIFgl/DEBYEXKlvcEa+9tHVcK8CF81Y2V72qaZhWA==", + "dev": true, + "license": "MIT", + "dependencies": { + "path-key": "^4.0.0", + "unicorn-magic": "^0.3.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/npm-run-path/node_modules/path-key": { + "version": "4.0.0", + "resolved": "https://registry.npmmirror.com/path-key/-/path-key-4.0.0.tgz", + "integrity": "sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/open": { + "version": "10.1.0", + "resolved": "https://registry.npmmirror.com/open/-/open-10.1.0.tgz", + "integrity": "sha512-mnkeQ1qP5Ue2wd+aivTD3NHd/lZ96Lu0jgf0pwktLPtx6cTZiH7tyeGRRHs0zX0rbrahXPnXlUnbeXyaBBuIaw==", + "dev": true, + "license": "MIT", + "dependencies": { + "default-browser": "^5.2.1", + "define-lazy-prop": "^3.0.0", + "is-inside-container": "^1.0.0", + "is-wsl": "^3.1.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/parse-ms": { + "version": "4.0.0", + "resolved": "https://registry.npmmirror.com/parse-ms/-/parse-ms-4.0.0.tgz", + "integrity": "sha512-TXfryirbmq34y8QBwgqCVLi+8oA3oWx2eAnSn62ITyEhEYaWRlVZ2DvMM9eZbMs/RfxPu/PK/aBLyGj4IrqMHw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/path-browserify": { + "version": "1.0.1", + "resolved": "https://registry.npmmirror.com/path-browserify/-/path-browserify-1.0.1.tgz", + "integrity": "sha512-b7uo2UCUOYZcnF/3ID0lulOJi/bafxa1xPe7ZPsammBSpjSWQkjNxlt635YGS2MiR9GjvuXCtz2emr3jbsz98g==", + "dev": true, + "license": "MIT" + }, + "node_modules/path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmmirror.com/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/pathe": { + "version": "1.1.2", + "resolved": "https://registry.npmmirror.com/pathe/-/pathe-1.1.2.tgz", + "integrity": "sha512-whLdWMYL2TwI08hn8/ZqAbrVemu0LNaNNJZX73O6qaIdCTfXutsLhMkjdENX0qhsQ9uIimo4/aQOmXkoon2nDQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/perfect-debounce": { + "version": "1.0.0", + "resolved": "https://registry.npmmirror.com/perfect-debounce/-/perfect-debounce-1.0.0.tgz", + "integrity": "sha512-xCy9V055GLEqoFaHoC1SoLIaLmWctgCUaBaWxDZ7/Zx4CTyX7cJQLJOok/orfjZAh9kEYpjJa4d0KcJmCbctZA==", + "dev": true, + "license": "MIT" + }, + "node_modules/picocolors": { + "version": "1.1.1", + "resolved": "https://registry.npmmirror.com/picocolors/-/picocolors-1.1.1.tgz", + "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", + "license": "ISC" + }, + "node_modules/picomatch": { + "version": "4.0.2", + "resolved": "https://registry.npmmirror.com/picomatch/-/picomatch-4.0.2.tgz", + "integrity": "sha512-M7BAV6Rlcy5u+m6oPhAPFgJTzAioX/6B0DxyvDlo9l8+T3nLKbrczg2WLUyzd45L8RqfUMyGPzekbMvX2Ldkwg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/pidtree": { + "version": "0.6.0", + "resolved": "https://registry.npmmirror.com/pidtree/-/pidtree-0.6.0.tgz", + "integrity": "sha512-eG2dWTVw5bzqGRztnHExczNxt5VGsE6OwTeCG3fdUf9KBsZzO3R5OIIIzWR+iZA0NtZ+RDVdaoE2dK1cn6jH4g==", + "dev": true, + "license": "MIT", + "bin": { + "pidtree": "bin/pidtree.js" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/pinia": { + "version": "2.3.1", + "resolved": "https://registry.npmmirror.com/pinia/-/pinia-2.3.1.tgz", + "integrity": "sha512-khUlZSwt9xXCaTbbxFYBKDc/bWAGWJjOgvxETwkTN7KRm66EeT1ZdZj6i2ceh9sP2Pzqsbc704r2yngBrxBVug==", + "license": "MIT", + "dependencies": { + "@vue/devtools-api": "^6.6.3", + "vue-demi": "^0.14.10" + }, + "funding": { + "url": "https://github.com/sponsors/posva" + }, + "peerDependencies": { + "typescript": ">=4.4.4", + "vue": "^2.7.0 || ^3.5.11" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/postcss": { + "version": "8.4.49", + "resolved": "https://registry.npmmirror.com/postcss/-/postcss-8.4.49.tgz", + "integrity": "sha512-OCVPnIObs4N29kxTjzLfUryOkvZEq+pf8jTF0lg8E7uETuWHA+v7j3c/xJmiqpX450191LlmZfUKkXxkTry7nA==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/postcss" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "nanoid": "^3.3.7", + "picocolors": "^1.1.1", + "source-map-js": "^1.2.1" + }, + "engines": { + "node": "^10 || ^12 || >=14" + } + }, + "node_modules/pretty-ms": { + "version": "9.2.0", + "resolved": "https://registry.npmmirror.com/pretty-ms/-/pretty-ms-9.2.0.tgz", + "integrity": "sha512-4yf0QO/sllf/1zbZWYnvWw3NxCQwLXKzIj0G849LSufP15BXKM0rbD2Z3wVnkMfjdn/CB0Dpp444gYAACdsplg==", + "dev": true, + "license": "MIT", + "dependencies": { + "parse-ms": "^4.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/proxy-from-env": { + "version": "1.1.0", + "resolved": "https://registry.npmmirror.com/proxy-from-env/-/proxy-from-env-1.1.0.tgz", + "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==", + "license": "MIT" + }, + "node_modules/read-package-json-fast": { + "version": "4.0.0", + "resolved": "https://registry.npmmirror.com/read-package-json-fast/-/read-package-json-fast-4.0.0.tgz", + "integrity": "sha512-qpt8EwugBWDw2cgE2W+/3oxC+KTez2uSVR8JU9Q36TXPAGCaozfQUs59v4j4GFpWTaw0i6hAZSvOmu1J0uOEUg==", + "dev": true, + "license": "ISC", + "dependencies": { + "json-parse-even-better-errors": "^4.0.0", + "npm-normalize-package-bin": "^4.0.0" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/rfdc": { + "version": "1.4.1", + "resolved": "https://registry.npmmirror.com/rfdc/-/rfdc-1.4.1.tgz", + "integrity": "sha512-q1b3N5QkRUWUl7iyylaaj3kOpIT0N2i9MqIEQXP73GVsN9cw3fdx8X63cEmWhJGi2PPCF23Ijp7ktmd39rawIA==", + "dev": true, + "license": "MIT" + }, + "node_modules/rollup": { + "version": "4.29.1", + "resolved": "https://registry.npmmirror.com/rollup/-/rollup-4.29.1.tgz", + "integrity": "sha512-RaJ45M/kmJUzSWDs1Nnd5DdV4eerC98idtUOVr6FfKcgxqvjwHmxc5upLF9qZU9EpsVzzhleFahrT3shLuJzIw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/estree": "1.0.6" + }, + "bin": { + "rollup": "dist/bin/rollup" + }, + "engines": { + "node": ">=18.0.0", + "npm": ">=8.0.0" + }, + "optionalDependencies": { + "@rollup/rollup-android-arm-eabi": "4.29.1", + "@rollup/rollup-android-arm64": "4.29.1", + "@rollup/rollup-darwin-arm64": "4.29.1", + "@rollup/rollup-darwin-x64": "4.29.1", + "@rollup/rollup-freebsd-arm64": "4.29.1", + "@rollup/rollup-freebsd-x64": "4.29.1", + "@rollup/rollup-linux-arm-gnueabihf": "4.29.1", + "@rollup/rollup-linux-arm-musleabihf": "4.29.1", + "@rollup/rollup-linux-arm64-gnu": "4.29.1", + "@rollup/rollup-linux-arm64-musl": "4.29.1", + "@rollup/rollup-linux-loongarch64-gnu": "4.29.1", + "@rollup/rollup-linux-powerpc64le-gnu": "4.29.1", + "@rollup/rollup-linux-riscv64-gnu": "4.29.1", + "@rollup/rollup-linux-s390x-gnu": "4.29.1", + "@rollup/rollup-linux-x64-gnu": "4.29.1", + "@rollup/rollup-linux-x64-musl": "4.29.1", + "@rollup/rollup-win32-arm64-msvc": "4.29.1", + "@rollup/rollup-win32-ia32-msvc": "4.29.1", + "@rollup/rollup-win32-x64-msvc": "4.29.1", + "fsevents": "~2.3.2" + } + }, + "node_modules/run-applescript": { + "version": "7.0.0", + "resolved": "https://registry.npmmirror.com/run-applescript/-/run-applescript-7.0.0.tgz", + "integrity": "sha512-9by4Ij99JUr/MCFBUkDKLWK3G9HVXmabKz9U5MlIAIuvuzkiOicRYs8XJLxX+xahD+mLiiCYDqF9dKAgtzKP1A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmmirror.com/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmmirror.com/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "dev": true, + "license": "MIT", + "dependencies": { + "shebang-regex": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmmirror.com/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/shell-quote": { + "version": "1.8.2", + "resolved": "https://registry.npmmirror.com/shell-quote/-/shell-quote-1.8.2.tgz", + "integrity": "sha512-AzqKpGKjrj7EM6rKVQEPpB288oCfnrEIuyoT9cyF4nmGa7V8Zk6f7RRqYisX8X9m+Q7bd632aZW4ky7EhbQztA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/signal-exit": { + "version": "4.1.0", + "resolved": "https://registry.npmmirror.com/signal-exit/-/signal-exit-4.1.0.tgz", + "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/sirv": { + "version": "3.0.0", + "resolved": "https://registry.npmmirror.com/sirv/-/sirv-3.0.0.tgz", + "integrity": "sha512-BPwJGUeDaDCHihkORDchNyyTvWFhcusy1XMmhEVTQTwGeybFbp8YEmB+njbPnth1FibULBSBVwCQni25XlCUDg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@polka/url": "^1.0.0-next.24", + "mrmime": "^2.0.0", + "totalist": "^3.0.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/source-map-js": { + "version": "1.2.1", + "resolved": "https://registry.npmmirror.com/source-map-js/-/source-map-js-1.2.1.tgz", + "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==", + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/speakingurl": { + "version": "14.0.1", + "resolved": "https://registry.npmmirror.com/speakingurl/-/speakingurl-14.0.1.tgz", + "integrity": "sha512-1POYv7uv2gXoyGFpBCmpDVSNV74IfsWlDW216UPjbWufNf+bSU6GdbDsxdcxtfwb4xlI3yxzOTKClUosxARYrQ==", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/strip-final-newline": { + "version": "4.0.0", + "resolved": "https://registry.npmmirror.com/strip-final-newline/-/strip-final-newline-4.0.0.tgz", + "integrity": "sha512-aulFJcD6YK8V1G7iRB5tigAP4TsHBZZrOV8pjV++zdUwmeV8uzbY7yn6h9MswN62adStNZFuCIx4haBnRuMDaw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/superjson": { + "version": "2.2.2", + "resolved": "https://registry.npmmirror.com/superjson/-/superjson-2.2.2.tgz", + "integrity": "sha512-5JRxVqC8I8NuOUjzBbvVJAKNM8qoVuH0O77h4WInc/qC2q5IreqKxYwgkga3PfA22OayK2ikceb/B26dztPl+Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "copy-anything": "^3.0.2" + }, + "engines": { + "node": ">=16" + } + }, + "node_modules/svg-tags": { + "version": "1.0.0", + "resolved": "https://registry.npmmirror.com/svg-tags/-/svg-tags-1.0.0.tgz", + "integrity": "sha512-ovssysQTa+luh7A5Weu3Rta6FJlFBBbInjOh722LIt6klpU2/HtdUbszju/G4devcvk8PGt7FCLv5wftu3THUA==", + "dev": true + }, + "node_modules/totalist": { + "version": "3.0.1", + "resolved": "https://registry.npmmirror.com/totalist/-/totalist-3.0.1.tgz", + "integrity": "sha512-sf4i37nQ2LBx4m3wB74y+ubopq6W/dIzXg0FDGjsYnZHVa1Da8FH853wlL2gtUhg+xJXjfk3kUZS3BRoQeoQBQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/tslib": { + "version": "2.3.0", + "resolved": "https://registry.npmmirror.com/tslib/-/tslib-2.3.0.tgz", + "integrity": "sha512-N82ooyxVNm6h1riLCoyS9e3fuJ3AMG2zIZs2Gd1ATcSFjSA23Q0fzjjZeh0jbJvWVDZ0cJT8yaNNaaXHzueNjg==", + "license": "0BSD" + }, + "node_modules/typescript": { + "version": "5.6.3", + "resolved": "https://registry.npmmirror.com/typescript/-/typescript-5.6.3.tgz", + "integrity": "sha512-hjcS1mhfuyi4WW8IWtjP7brDrG2cuDZukyrYrSauoXGNgx0S7zceP07adYkJycEr56BOUTNPzbInooiN3fn1qw==", + "devOptional": true, + "license": "Apache-2.0", + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=14.17" + } + }, + "node_modules/undici-types": { + "version": "6.20.0", + "resolved": "https://registry.npmmirror.com/undici-types/-/undici-types-6.20.0.tgz", + "integrity": "sha512-Ny6QZ2Nju20vw1SRHe3d9jVu6gJ+4e3+MMpqu7pqE5HT6WsTSlce++GQmK5UXS8mzV8DSYHrQH+Xrf2jVcuKNg==", + "dev": true, + "license": "MIT" + }, + "node_modules/unicorn-magic": { + "version": "0.3.0", + "resolved": "https://registry.npmmirror.com/unicorn-magic/-/unicorn-magic-0.3.0.tgz", + "integrity": "sha512-+QBBXBCvifc56fsbuxZQ6Sic3wqqc3WWaqxs58gvJrcOuN83HGTCwz3oS5phzU9LthRNE9VrJCFCLUgHeeFnfA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/universalify": { + "version": "2.0.1", + "resolved": "https://registry.npmmirror.com/universalify/-/universalify-2.0.1.tgz", + "integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 10.0.0" + } + }, + "node_modules/update-browserslist-db": { + "version": "1.1.1", + "resolved": "https://registry.npmmirror.com/update-browserslist-db/-/update-browserslist-db-1.1.1.tgz", + "integrity": "sha512-R8UzCaa9Az+38REPiJ1tXlImTJXlVfgHZsglwBD/k6nj76ctsH1E3q4doGrukiLQd3sGQYu56r5+lo5r94l29A==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "escalade": "^3.2.0", + "picocolors": "^1.1.0" + }, + "bin": { + "update-browserslist-db": "cli.js" + }, + "peerDependencies": { + "browserslist": ">= 4.21.0" + } + }, + "node_modules/vite": { + "version": "6.0.6", + "resolved": "https://registry.npmmirror.com/vite/-/vite-6.0.6.tgz", + "integrity": "sha512-NSjmUuckPmDU18bHz7QZ+bTYhRR0iA72cs2QAxCqDpafJ0S6qetco0LB3WW2OxlMHS0JmAv+yZ/R3uPmMyGTjQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "esbuild": "^0.24.2", + "postcss": "^8.4.49", + "rollup": "^4.23.0" + }, + "bin": { + "vite": "bin/vite.js" + }, + "engines": { + "node": "^18.0.0 || ^20.0.0 || >=22.0.0" + }, + "funding": { + "url": "https://github.com/vitejs/vite?sponsor=1" + }, + "optionalDependencies": { + "fsevents": "~2.3.3" + }, + "peerDependencies": { + "@types/node": "^18.0.0 || ^20.0.0 || >=22.0.0", + "jiti": ">=1.21.0", + "less": "*", + "lightningcss": "^1.21.0", + "sass": "*", + "sass-embedded": "*", + "stylus": "*", + "sugarss": "*", + "terser": "^5.16.0", + "tsx": "^4.8.1", + "yaml": "^2.4.2" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + }, + "jiti": { + "optional": true + }, + "less": { + "optional": true + }, + "lightningcss": { + "optional": true + }, + "sass": { + "optional": true + }, + "sass-embedded": { + "optional": true + }, + "stylus": { + "optional": true + }, + "sugarss": { + "optional": true + }, + "terser": { + "optional": true + }, + "tsx": { + "optional": true + }, + "yaml": { + "optional": true + } + } + }, + "node_modules/vite-hot-client": { + "version": "0.2.4", + "resolved": "https://registry.npmmirror.com/vite-hot-client/-/vite-hot-client-0.2.4.tgz", + "integrity": "sha512-a1nzURqO7DDmnXqabFOliz908FRmIppkBKsJthS8rbe8hBEXwEwe4C3Pp33Z1JoFCYfVL4kTOMLKk0ZZxREIeA==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/antfu" + }, + "peerDependencies": { + "vite": "^2.6.0 || ^3.0.0 || ^4.0.0 || ^5.0.0-0 || ^6.0.0-0" + } + }, + "node_modules/vite-plugin-inspect": { + "version": "0.8.9", + "resolved": "https://registry.npmmirror.com/vite-plugin-inspect/-/vite-plugin-inspect-0.8.9.tgz", + "integrity": "sha512-22/8qn+LYonzibb1VeFZmISdVao5kC22jmEKm24vfFE8siEn47EpVcCLYMv6iKOYMJfjSvSJfueOwcFCkUnV3A==", + "dev": true, + "license": "MIT", + "dependencies": { + "@antfu/utils": "^0.7.10", + "@rollup/pluginutils": "^5.1.3", + "debug": "^4.3.7", + "error-stack-parser-es": "^0.1.5", + "fs-extra": "^11.2.0", + "open": "^10.1.0", + "perfect-debounce": "^1.0.0", + "picocolors": "^1.1.1", + "sirv": "^3.0.0" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/antfu" + }, + "peerDependencies": { + "vite": "^3.1.0 || ^4.0.0 || ^5.0.0-0 || ^6.0.1" + }, + "peerDependenciesMeta": { + "@nuxt/kit": { + "optional": true + } + } + }, + "node_modules/vite-plugin-vue-devtools": { + "version": "7.6.8", + "resolved": "https://registry.npmmirror.com/vite-plugin-vue-devtools/-/vite-plugin-vue-devtools-7.6.8.tgz", + "integrity": "sha512-32aIps8C1Y7UEoqyWf+ES3J1OozsCYMIqTqd+I5qass+R0Tcf8SaA2bX1/rskAzkcKCteVoBjEENmqwTcMebbw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@vue/devtools-core": "^7.6.8", + "@vue/devtools-kit": "^7.6.8", + "@vue/devtools-shared": "^7.6.8", + "execa": "^9.5.1", + "sirv": "^3.0.0", + "vite-plugin-inspect": "~0.8.9", + "vite-plugin-vue-inspector": "^5.3.1" + }, + "engines": { + "node": ">=v14.21.3" + }, + "peerDependencies": { + "vite": "^3.1.0 || ^4.0.0-0 || ^5.0.0-0 || ^6.0.0-0" + } + }, + "node_modules/vite-plugin-vue-inspector": { + "version": "5.3.1", + "resolved": "https://registry.npmmirror.com/vite-plugin-vue-inspector/-/vite-plugin-vue-inspector-5.3.1.tgz", + "integrity": "sha512-cBk172kZKTdvGpJuzCCLg8lJ909wopwsu3Ve9FsL1XsnLBiRT9U3MePcqrgGHgCX2ZgkqZmAGR8taxw+TV6s7A==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/core": "^7.23.0", + "@babel/plugin-proposal-decorators": "^7.23.0", + "@babel/plugin-syntax-import-attributes": "^7.22.5", + "@babel/plugin-syntax-import-meta": "^7.10.4", + "@babel/plugin-transform-typescript": "^7.22.15", + "@vue/babel-plugin-jsx": "^1.1.5", + "@vue/compiler-dom": "^3.3.4", + "kolorist": "^1.8.0", + "magic-string": "^0.30.4" + }, + "peerDependencies": { + "vite": "^3.0.0-0 || ^4.0.0-0 || ^5.0.0-0 || ^6.0.0-0" + } + }, + "node_modules/vscode-uri": { + "version": "3.0.8", + "resolved": "https://registry.npmmirror.com/vscode-uri/-/vscode-uri-3.0.8.tgz", + "integrity": "sha512-AyFQ0EVmsOZOlAnxoFOGOq1SQDWAB7C6aqMGS23svWAllfOaxbuFvcT8D1i8z3Gyn8fraVeZNNmN6e9bxxXkKw==", + "dev": true, + "license": "MIT" + }, + "node_modules/vue": { + "version": "3.5.13", + "resolved": "https://registry.npmmirror.com/vue/-/vue-3.5.13.tgz", + "integrity": "sha512-wmeiSMxkZCSc+PM2w2VRsOYAZC8GdipNFRTsLSfodVqI9mbejKeXEGr8SckuLnrQPGe3oJN5c3K0vpoU9q/wCQ==", + "license": "MIT", + "dependencies": { + "@vue/compiler-dom": "3.5.13", + "@vue/compiler-sfc": "3.5.13", + "@vue/runtime-dom": "3.5.13", + "@vue/server-renderer": "3.5.13", + "@vue/shared": "3.5.13" + }, + "peerDependencies": { + "typescript": "*" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/vue-demi": { + "version": "0.14.10", + "resolved": "https://registry.npmmirror.com/vue-demi/-/vue-demi-0.14.10.tgz", + "integrity": "sha512-nMZBOwuzabUO0nLgIcc6rycZEebF6eeUfaiQx9+WSk8e29IbLvPU9feI6tqW4kTo3hvoYAJkMh8n8D0fuISphg==", + "hasInstallScript": true, + "license": "MIT", + "bin": { + "vue-demi-fix": "bin/vue-demi-fix.js", + "vue-demi-switch": "bin/vue-demi-switch.js" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/antfu" + }, + "peerDependencies": { + "@vue/composition-api": "^1.0.0-rc.1", + "vue": "^3.0.0-0 || ^2.6.0" + }, + "peerDependenciesMeta": { + "@vue/composition-api": { + "optional": true + } + } + }, + "node_modules/vue-router": { + "version": "4.5.0", + "resolved": "https://registry.npmmirror.com/vue-router/-/vue-router-4.5.0.tgz", + "integrity": "sha512-HDuk+PuH5monfNuY+ct49mNmkCRK4xJAV9Ts4z9UFc4rzdDnxQLyCMGGc8pKhZhHTVzfanpNwB/lwqevcBwI4w==", + "license": "MIT", + "dependencies": { + "@vue/devtools-api": "^6.6.4" + }, + "funding": { + "url": "https://github.com/sponsors/posva" + }, + "peerDependencies": { + "vue": "^3.2.0" + } + }, + "node_modules/vue-tsc": { + "version": "2.2.0", + "resolved": "https://registry.npmmirror.com/vue-tsc/-/vue-tsc-2.2.0.tgz", + "integrity": "sha512-gtmM1sUuJ8aSb0KoAFmK9yMxb8TxjewmxqTJ1aKphD5Cbu0rULFY6+UQT51zW7SpUcenfPUuflKyVwyx9Qdnxg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@volar/typescript": "~2.4.11", + "@vue/language-core": "2.2.0" + }, + "bin": { + "vue-tsc": "bin/vue-tsc.js" + }, + "peerDependencies": { + "typescript": ">=5.0.0" + } + }, + "node_modules/which": { + "version": "5.0.0", + "resolved": "https://registry.npmmirror.com/which/-/which-5.0.0.tgz", + "integrity": "sha512-JEdGzHwwkrbWoGOlIHqQ5gtprKGOenpDHpxE9zVR1bWbOtYRyPPHMe9FaP6x61CmNaTThSkb0DAJte5jD+DmzQ==", + "dev": true, + "license": "ISC", + "dependencies": { + "isexe": "^3.1.1" + }, + "bin": { + "node-which": "bin/which.js" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/yallist": { + "version": "3.1.1", + "resolved": "https://registry.npmmirror.com/yallist/-/yallist-3.1.1.tgz", + "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", + "dev": true, + "license": "ISC" + }, + "node_modules/yoctocolors": { + "version": "2.1.1", + "resolved": "https://registry.npmmirror.com/yoctocolors/-/yoctocolors-2.1.1.tgz", + "integrity": "sha512-GQHQqAopRhwU8Kt1DDM8NjibDXHC8eoh1erhGAJPEyveY9qqVeXvVikNKrDz69sHowPMorbPUrH/mx8c50eiBQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/zrender": { + "version": "5.6.1", + "resolved": "https://registry.npmmirror.com/zrender/-/zrender-5.6.1.tgz", + "integrity": "sha512-OFXkDJKcrlx5su2XbzJvj/34Q3m6PvyCZkVPHGYpcCJ52ek4U/ymZyfuV1nKE23AyBJ51E/6Yr0mhZ7xGTO4ag==", + "license": "BSD-3-Clause", + "dependencies": { + "tslib": "2.3.0" + } + } + } +} diff --git a/package.json b/package.json new file mode 100644 index 0000000..28a4d37 --- /dev/null +++ b/package.json @@ -0,0 +1,32 @@ +{ + "name": "asideviewts", + "version": "0.0.0", + "private": true, + "type": "module", + "scripts": { + "dev": "vite", + "build": "run-p type-check \"build-only {@}\" --", + "preview": "vite preview", + "build-only": "vite build", + "type-check": "vue-tsc --build" + }, + "dependencies": { + "axios": "^1.7.9", + "echarts": "^5.6.0", + "element-plus": "^2.9.1", + "pinia": "^2.3.1", + "vue": "^3.5.13", + "vue-router": "^4.5.0" + }, + "devDependencies": { + "@tsconfig/node22": "^22.0.0", + "@types/node": "^22.10.2", + "@vitejs/plugin-vue": "^5.2.1", + "@vue/tsconfig": "^0.7.0", + "npm-run-all2": "^7.0.2", + "typescript": "~5.6.3", + "vite": "^6.0.5", + "vite-plugin-vue-devtools": "^7.6.8", + "vue-tsc": "^2.1.10" + } +} diff --git a/public/favicon.ico b/public/favicon.ico new file mode 100644 index 0000000000000000000000000000000000000000..df36fcfb72584e00488330b560ebcf34a41c64c2 GIT binary patch literal 4286 zcmds*O-Phc6o&64GDVCEQHxsW(p4>LW*W<827=Unuo8sGpRux(DN@jWP-e29Wl%wj zY84_aq9}^Am9-cWTD5GGEo#+5Fi2wX_P*bo+xO!)p*7B;iKlbFd(U~_d(U?#hLj56 zPhFkj-|A6~Qk#@g^#D^U0XT1cu=c-vu1+SElX9NR;kzAUV(q0|dl0|%h|dI$%VICy zJnu2^L*Te9JrJMGh%-P79CL0}dq92RGU6gI{v2~|)p}sG5x0U*z<8U;Ij*hB9z?ei z@g6Xq-pDoPl=MANPiR7%172VA%r)kev<ISBgE$F{SFy+(=9Z)f)De0Se}ZDZW}Z3B zElCeVrw;K0Fdl_Cg=gZOFXXc3pL)Q05CAuT+XucQ<8g~3dteP~|7s7c6QYP;fy;mF zMN;>tV-_5H*QJKFmd;8yA$98zCxBZYXTNZ#QFk2(TX0;Y2dt&WitL#$96|gJY=3xX zpCoi|YNzgO3R`f@IiEeSmKrPSf#h#Qd<$%Ej^RIeeYfsxhPMOG`S`Pz8q``=511zm zAm)MX5AV^5xIWPyEu7u>qYs?pn$I4nL9J!=K=SGlKLXpE<5x+2cDTXq?brj?n6sp= zphe9;_JHf40^9~}9i08r{XM$7HB!`{Ys~TK0kx<}ZQng`UPvH*11|q7&l9?@FQz;8 zx!=3<4seY*%=OlbCbcae?<QnEgvj4i?s}Yk=qA2z`-^*<eK3c)MS4JOdbsTQEOa0) z0NWqlna2rzs>5^V_}*K>Uo6ZWV8mTyE^B=DKy7-sdLYkR5Z?paTgK-zyIkKjIcpyO z{+uIt&YSa_$QnN_@t~L014dyK(fOOo+W*MIxbA6Ndgr=Y!f#Tokqv}n<7-9qfHkc3 z=>a|HWqcX8fzQCT=dqVbogRq!-S>H%yA{1w#2Pn;=e>JiEj7Hl;zdt-2f+j2%DeVD zsW0Ab)ZK@0cIW%W7<X*Er!BfRbvU93$DH%#v6dRt^6HBxz1xBNHx=$&_Gv<&J}Ljk zJN<Fzx(`Oe@KgQ0F$<14=XV#WK`o#6Ku>z}H{&~yGhn~D;aiP4=;m-HCo`BEI+Kd6 z={Xwx{T<?%b6i9IjI)Ls)S{-*mq<@~R{?$}ZKjf;^k75i_}(2MXt}^SEBVg7AI@28 zo_uPg2V)_e-`2Ois=PYoe%9u*n9({PFR)OnHJPi{dNx>Kx<YG`4QQ>D#iCLfl2<BD h7L=-;Q>vQGDitKtN>z|-AdCN|$jTFDg0m3O`WLD4_s#$S literal 0 HcmV?d00001 diff --git a/src/App.vue b/src/App.vue new file mode 100644 index 0000000..7f75105 --- /dev/null +++ b/src/App.vue @@ -0,0 +1,9 @@ +<script setup lang="ts"> + +import { RouterView } from 'vue-router' +</script> + +<template> + <RouterView /> +</template> + diff --git a/src/assets/base.css b/src/assets/base.css new file mode 100644 index 0000000..21362b7 --- /dev/null +++ b/src/assets/base.css @@ -0,0 +1,101 @@ +/* color palette from <https://github.com/vuejs/theme> */ +:root { + --vt-c-white: #ffffff; + --vt-c-white-soft: #f8f8f8; + --vt-c-white-mute: #f2f2f2; + + --vt-c-black: #181818; + --vt-c-black-soft: #222222; + --vt-c-black-mute: #282828; + + --vt-c-indigo: #2c3e50; + + --vt-c-divider-light-1: rgba(60, 60, 60, 0.29); + --vt-c-divider-light-2: rgba(60, 60, 60, 0.12); + --vt-c-divider-dark-1: rgba(84, 84, 84, 0.65); + --vt-c-divider-dark-2: rgba(84, 84, 84, 0.48); + + --vt-c-text-light-1: var(--vt-c-indigo); + --vt-c-text-light-2: rgba(60, 60, 60, 0.66); + --vt-c-text-dark-1: var(--vt-c-white); + --vt-c-text-dark-2: rgb(168, 168, 168); + + + --my-common-bgc-1:#fff; + --my-common-bgc-2:#1F1F1F; + --my-common-fc-1:#fff; + --my-common-fc-2:#000; + + --my-light-bgc-1: #ffffff; + --my-light-bgc-2: #000000; + + --my-light-br-1: #e7ebf3; + --my-light-br-2: #ffffff; + + --my-light-fc-1: #414040; + --my-light-fc-2: #414040; +} + +/* semantic color variables for this project */ +/* :root { + --color-background: var(--vt-c-white); + --color-background-soft: var(--vt-c-white-soft); + --color-background-mute: var(--vt-c-white-mute); + + --color-border: var(--vt-c-divider-light-2); + --color-border-hover: var(--vt-c-divider-light-1); + + --color-heading: var(--vt-c-text-light-1); + --color-text: var(--vt-c-text-light-1); + + --section-gap: 160px; +} + +@media (prefers-color-scheme: dark) { + :root { + --color-background: var(--vt-c-black); + --color-background-soft: var(--vt-c-black-soft); + --color-background-mute: var(--vt-c-black-mute); + + --color-border: var(--vt-c-divider-dark-2); + --color-border-hover: var(--vt-c-divider-dark-1); + + --color-heading: var(--vt-c-text-dark-1); + --color-text: var(--vt-c-text-dark-2); + } +} + +*, +*::before, +*::after { + box-sizing: border-box; + margin: 0; + font-weight: normal; +} + +body { + min-height: 100vh; + color: var(--color-text); + background: var(--color-background); + transition: + color 0.5s, + background-color 0.5s; + line-height: 1.6; + font-family: + Inter, + -apple-system, + BlinkMacSystemFont, + 'Segoe UI', + Roboto, + Oxygen, + Ubuntu, + Cantarell, + 'Fira Sans', + 'Droid Sans', + 'Helvetica Neue', + sans-serif; + font-size: 15px; + text-rendering: optimizeLegibility; + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; +} */ diff --git a/src/assets/logo.svg b/src/assets/logo.svg new file mode 100644 index 0000000..7565660 --- /dev/null +++ b/src/assets/logo.svg @@ -0,0 +1 @@ +<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 261.76 226.69"><path d="M161.096.001l-30.225 52.351L100.647.001H-.005l130.877 226.688L261.749.001z" fill="#41b883"/><path d="M161.096.001l-30.225 52.351L100.647.001H52.346l78.526 136.01L209.398.001z" fill="#34495e"/></svg> diff --git a/src/assets/main.css b/src/assets/main.css new file mode 100644 index 0000000..36fb845 --- /dev/null +++ b/src/assets/main.css @@ -0,0 +1,35 @@ +@import './base.css'; + +#app { + max-width: 1280px; + margin: 0 auto; + padding: 2rem; + font-weight: normal; +} + +a, +.green { + text-decoration: none; + color: hsla(160, 100%, 37%, 1); + transition: 0.4s; + padding: 3px; +} + +@media (hover: hover) { + a:hover { + background-color: hsla(160, 100%, 37%, 0.2); + } +} + +@media (min-width: 1024px) { + body { + display: flex; + place-items: center; + } + + #app { + display: grid; + grid-template-columns: 1fr 1fr; + padding: 0 2rem; + } +} diff --git a/src/end/DayDesign.vue b/src/end/DayDesign.vue new file mode 100644 index 0000000..b53221d --- /dev/null +++ b/src/end/DayDesign.vue @@ -0,0 +1,840 @@ +<script setup> +import { onMounted, inject, ref, nextTick, onUnmounted, onBeforeUnmount } from 'vue' + +// 引入pinia +import useEcharts from '@/store/usethemestore' +const echartsState = useEcharts() +echartsState.optionConfigData() + +//引入echarts +let echarts = inject('echarts') + +// 外层盒子容器,为了计算图形在内部的高度分配问题 +const chartsInfo = ref(null) +// K线图的容器 +const mKline = ref(null) + +// 存储各个图形所分配的高度信息 +let heightList = ref([]) +// 计算高度、设置高度 +const dynamicsHeight = () => { + // 高度 + let domHeightList = chartsInfo.value.offsetHeight + // 判断是否进行了底部选项的点击事件,如果点击了则会往数组中添加信息,则长度就会改变 + + if (clicklist.value.length) { + // 先清空数组,避免 + heightList.value = [] + // 将处理过后的数据加入数组 + heightList.value.push(domHeightList * (1 - clicklist.value.length * 0.15)) + // 设置最上面K线图的高度 + mKline.value.style.height = `${heightList.value[0]}px` + // 设置新添加图表的高度 + heightList.value.push(domHeightList * 0.15) + + console.log(heightList.value) + } else { + // 先清空数组,避免之前的数据没有被清空 + heightList.value = [] + + // 设置只有K线图的高度的父容器的全部大小 + mKline.value.style.height = `${domHeightList}px` + } +} + +// 定义图表配置数组 +let chartConfigs = ref([ + { + id: 1, + name: 'MAVOL', + attId: 'charts1', + status: false, + options: { + tooltip: { + trigger: 'axis', // 触发类型为坐标轴 + axisPointer: { + // 坐标轴指示器 + type: 'cross', // 类型为交叉 + label: { + backgroundColor: '#6a7985', // 标签背景色 + }, + }, + }, + dataZoom: [ + { + type: 'inside', + xAxisIndex: [0, 0], + start: 20, + end: 100, + }, + ], + xAxis: { + type: 'category', + boundaryGap: false, + data: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'], + }, + yAxis: { + type: 'value', + }, + series: [ + { + name: 'Email', + type: 'line', + stack: 'Total', + data: [120, 132, 101, 134, 90, 230, 210], + }, + { + name: 'Union Ads', + type: 'line', + stack: 'Total', + data: [220, 182, 191, 234, 290, 330, 310], + }, + { + name: 'Video Ads', + type: 'line', + stack: 'Total', + data: [150, 232, 201, 154, 190, 330, 410], + }, + { + name: 'Direct', + type: 'line', + stack: 'Total', + data: [320, 332, 301, 334, 390, 330, 320], + }, + { + name: 'Search Engine', + type: 'line', + stack: 'Total', + data: [820, 932, 901, 934, 1290, 1330, 1320], + }, + ], + }, + }, + { + id: 2, + name: 'VOL', + attId: 'charts2', + status: false, + options: { + // title: { + // text: 'Stacked Area Chart', + // }, + // tooltip: { + // trigger: 'axis', + // axisPointer: { + // type: 'cross', + // label: { + // backgroundColor: '#6a7985', + // }, + // }, + // }, + // legend: { + // data: ['Email', 'Union Ads', 'Video Ads', 'Direct', 'Search Engine'], + // }, + // toolbox: { + // feature: { + // saveAsImage: {}, + // }, + // }, + // grid: { + // left: '3%', + // right: '4%', + // bottom: '3%', + // containLabel: true, + // }, + dataZoom: [ + { + type: 'inside', + xAxisIndex: [0, 0], + start: 20, + end: 100, + }, + ], + xAxis: [ + { + type: 'category', + boundaryGap: false, + data: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'], + }, + ], + yAxis: [ + { + type: 'value', + }, + ], + series: [ + { + name: 'Email', + type: 'line', + stack: 'Total', + areaStyle: {}, + emphasis: { + focus: 'series', + }, + data: [120, 132, 101, 134, 90, 230, 210], + }, + { + name: 'Union Ads', + type: 'line', + stack: 'Total', + areaStyle: {}, + emphasis: { + focus: 'series', + }, + data: [220, 182, 191, 234, 290, 330, 310], + }, + { + name: 'Video Ads', + type: 'line', + stack: 'Total', + areaStyle: {}, + emphasis: { + focus: 'series', + }, + data: [150, 232, 201, 154, 190, 330, 410], + }, + { + name: 'Direct', + type: 'line', + stack: 'Total', + areaStyle: {}, + emphasis: { + focus: 'series', + }, + data: [320, 332, 301, 334, 390, 330, 320], + }, + { + name: 'Search Engine', + type: 'line', + stack: 'Total', + label: { + show: true, + position: 'top', + }, + areaStyle: {}, + emphasis: { + focus: 'series', + }, + data: [820, 932, 901, 934, 1290, 1330, 1320], + }, + ], + }, + }, + { + id: 3, + name: 'MACD', + attId: 'charts3', + status: false, + options:{ + dataZoom: [ + { + type: 'inside', + xAxisIndex: [0, 0], + start: 20, + end: 100, + }, + ], + } + }, + { + id: 4, + name: 'KDJ', + attId: 'charts4', + status: false, + options:{ + dataZoom: [ + { + type: 'inside', + xAxisIndex: [0, 0], + start: 20, + end: 100, + }, + ], + } + }, + { + id: 5, + name: 'RSI', + attId: 'charts5', + status: false, + options:{ + dataZoom: [ + { + type: 'inside', + xAxisIndex: [0, 0], + start: 20, + end: 100, + }, + ], + } + }, +]) + +// 储存点击底部选项的状态的数据 +const clicklist = ref([]) + +// 处理点击事件并添加图表 +const addChart = (item) => { + // 判断当前点击的图表的状态,如果已经存在则不进行操作 + if (clicklist.value.includes(item.name)) { + // 移除图表 + echarts.dispose(item.name) + // 先移除当前的图表信息 + clicklist.value = clicklist.value.filter((content) => content !== item.name) + // 遍历数组,找到对应名称的图表并设置状态为false + chartConfigs.value.forEach((element) => { + if (element.name == item.name) { + element.status = false + } + }) + // 调用高度计算函数,重新分配高度 + dynamicsHeight() + // 延迟执行,确保图表已经创建 + nextTick(() => { + chartConfigs.value.forEach((element) => { + if (element.name == item.name) { + element.status = false + // 调用configecharts函数,刷新图表,防止图形重叠 + configecharts() + } + }) + }) + } else { + // 往数组里面添加参数信息 + clicklist.value.push(item.name) + // 遍历数组,找到对应名称的图表并设置状态为true + chartConfigs.value.forEach((element) => { + if (element.name == item.name) { + element.status = true + } + }) + // 调用高度计算函数,重新分配高度 + dynamicsHeight() + // 延迟执行,确保图表已经创建 + nextTick(() => { + chartConfigs.value.forEach((element) => { + if (element.name == item.name) { + element.status = true + // 调用configecharts函数,刷新图表,防止图形重叠 + configecharts() + // 调用commonecharts函数,会根据传入的参数进行图表的绘制 + commonecharts(item.attId, item.options) + } + }) + }) + } +} + + + + + + +const upColor = '#ec0000'; +const upBorderColor = '#8A0000'; +const downColor = '#00da3c'; +const downBorderColor = '#008F28'; +// Each item: open,close,lowest,highest +const data0 = splitData([ + ['2013/1/24', 2320.26, 2320.26, 2287.3, 2362.94], + ['2013/1/25', 2300, 2291.3, 2288.26, 2308.38], + ['2013/1/28', 2295.35, 2346.5, 2295.35, 2346.92], + ['2013/1/29', 2347.22, 2358.98, 2337.35, 2363.8], + ['2013/1/30', 2360.75, 2382.48, 2347.89, 2383.76], + ['2013/1/31', 2383.43, 2385.42, 2371.23, 2391.82], + ['2013/2/1', 2377.41, 2419.02, 2369.57, 2421.15], + ['2013/2/4', 2425.92, 2428.15, 2417.58, 2440.38], + ['2013/2/5', 2411, 2433.13, 2403.3, 2437.42], + ['2013/2/6', 2432.68, 2434.48, 2427.7, 2441.73], + ['2013/2/7', 2430.69, 2418.53, 2394.22, 2433.89], + ['2013/2/8', 2416.62, 2432.4, 2414.4, 2443.03], + ['2013/2/18', 2441.91, 2421.56, 2415.43, 2444.8], + ['2013/2/19', 2420.26, 2382.91, 2373.53, 2427.07], + ['2013/2/20', 2383.49, 2397.18, 2370.61, 2397.94], + ['2013/2/21', 2378.82, 2325.95, 2309.17, 2378.82], + ['2013/2/22', 2322.94, 2314.16, 2308.76, 2330.88], + ['2013/2/25', 2320.62, 2325.82, 2315.01, 2338.78], + ['2013/2/26', 2313.74, 2293.34, 2289.89, 2340.71], + ['2013/2/27', 2297.77, 2313.22, 2292.03, 2324.63], + ['2013/2/28', 2322.32, 2365.59, 2308.92, 2366.16], + ['2013/3/1', 2364.54, 2359.51, 2330.86, 2369.65], + ['2013/3/4', 2332.08, 2273.4, 2259.25, 2333.54], + ['2013/3/5', 2274.81, 2326.31, 2270.1, 2328.14], + ['2013/3/6', 2333.61, 2347.18, 2321.6, 2351.44], + ['2013/3/7', 2340.44, 2324.29, 2304.27, 2352.02], + ['2013/3/8', 2326.42, 2318.61, 2314.59, 2333.67], + ['2013/3/11', 2314.68, 2310.59, 2296.58, 2320.96], + ['2013/3/12', 2309.16, 2286.6, 2264.83, 2333.29], + ['2013/3/13', 2282.17, 2263.97, 2253.25, 2286.33], + ['2013/3/14', 2255.77, 2270.28, 2253.31, 2276.22], + ['2013/3/15', 2269.31, 2278.4, 2250, 2312.08], + ['2013/3/18', 2267.29, 2240.02, 2239.21, 2276.05], + ['2013/3/19', 2244.26, 2257.43, 2232.02, 2261.31], + ['2013/3/20', 2257.74, 2317.37, 2257.42, 2317.86], + ['2013/3/21', 2318.21, 2324.24, 2311.6, 2330.81], + ['2013/3/22', 2321.4, 2328.28, 2314.97, 2332], + ['2013/3/25', 2334.74, 2326.72, 2319.91, 2344.89], + ['2013/3/26', 2318.58, 2297.67, 2281.12, 2319.99], + ['2013/3/27', 2299.38, 2301.26, 2289, 2323.48], + ['2013/3/28', 2273.55, 2236.3, 2232.91, 2273.55], + ['2013/3/29', 2238.49, 2236.62, 2228.81, 2246.87], + ['2013/4/1', 2229.46, 2234.4, 2227.31, 2243.95], + ['2013/4/2', 2234.9, 2227.74, 2220.44, 2253.42], + ['2013/4/3', 2232.69, 2225.29, 2217.25, 2241.34], + ['2013/4/8', 2196.24, 2211.59, 2180.67, 2212.59], + ['2013/4/9', 2215.47, 2225.77, 2215.47, 2234.73], + ['2013/4/10', 2224.93, 2226.13, 2212.56, 2233.04], + ['2013/4/11', 2236.98, 2219.55, 2217.26, 2242.48], + ['2013/4/12', 2218.09, 2206.78, 2204.44, 2226.26], + ['2013/4/15', 2199.91, 2181.94, 2177.39, 2204.99], + ['2013/4/16', 2169.63, 2194.85, 2165.78, 2196.43], + ['2013/4/17', 2195.03, 2193.8, 2178.47, 2197.51], + ['2013/4/18', 2181.82, 2197.6, 2175.44, 2206.03], + ['2013/4/19', 2201.12, 2244.64, 2200.58, 2250.11], + ['2013/4/22', 2236.4, 2242.17, 2232.26, 2245.12], + ['2013/4/23', 2242.62, 2184.54, 2182.81, 2242.62], + ['2013/4/24', 2187.35, 2218.32, 2184.11, 2226.12], + ['2013/4/25', 2213.19, 2199.31, 2191.85, 2224.63], + ['2013/4/26', 2203.89, 2177.91, 2173.86, 2210.58], + ['2013/5/2', 2170.78, 2174.12, 2161.14, 2179.65], + ['2013/5/3', 2179.05, 2205.5, 2179.05, 2222.81], + ['2013/5/6', 2212.5, 2231.17, 2212.5, 2236.07], + ['2013/5/7', 2227.86, 2235.57, 2219.44, 2240.26], + ['2013/5/8', 2242.39, 2246.3, 2235.42, 2255.21], + ['2013/5/9', 2246.96, 2232.97, 2221.38, 2247.86], + ['2013/5/10', 2228.82, 2246.83, 2225.81, 2247.67], + ['2013/5/13', 2247.68, 2241.92, 2231.36, 2250.85], + ['2013/5/14', 2238.9, 2217.01, 2205.87, 2239.93], + ['2013/5/15', 2217.09, 2224.8, 2213.58, 2225.19], + ['2013/5/16', 2221.34, 2251.81, 2210.77, 2252.87], + ['2013/5/17', 2249.81, 2282.87, 2248.41, 2288.09], + ['2013/5/20', 2286.33, 2299.99, 2281.9, 2309.39], + ['2013/5/21', 2297.11, 2305.11, 2290.12, 2305.3], + ['2013/5/22', 2303.75, 2302.4, 2292.43, 2314.18], + ['2013/5/23', 2293.81, 2275.67, 2274.1, 2304.95], + ['2013/5/24', 2281.45, 2288.53, 2270.25, 2292.59], + ['2013/5/27', 2286.66, 2293.08, 2283.94, 2301.7], + ['2013/5/28', 2293.4, 2321.32, 2281.47, 2322.1], + ['2013/5/29', 2323.54, 2324.02, 2321.17, 2334.33], + ['2013/5/30', 2316.25, 2317.75, 2310.49, 2325.72], + ['2013/5/31', 2320.74, 2300.59, 2299.37, 2325.53], + ['2013/6/3', 2300.21, 2299.25, 2294.11, 2313.43], + ['2013/6/4', 2297.1, 2272.42, 2264.76, 2297.1], + ['2013/6/5', 2270.71, 2270.93, 2260.87, 2276.86], + ['2013/6/6', 2264.43, 2242.11, 2240.07, 2266.69], + ['2013/6/7', 2242.26, 2210.9, 2205.07, 2250.63], + ['2013/6/13', 2190.1, 2148.35, 2126.22, 2190.1] +]); +function splitData(rawData) { + const categoryData = []; + const values = []; + for (var i = 0; i < rawData.length; i++) { + categoryData.push(rawData[i].splice(0, 1)[0]); + values.push(rawData[i]); + } + return { + categoryData: categoryData, + values: values + }; +} +function calculateMA(dayCount) { + var result = []; + for (var i = 0, len = data0.values.length; i < len; i++) { + if (i < dayCount) { + result.push('-'); + continue; + } + var sum = 0; + for (var j = 0; j < dayCount; j++) { + sum += +data0.values[i - j][1]; + } + result.push(sum / dayCount); + } + return result; +} + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +// 绘制初始的Echarts图表,始终会在页面中。并返回当前图表的实例化信息,便于使用echarts.connect()进行连接 +const configecharts = (options = {}) => { + // 先将容器中的_echarts_instance_清除,不处理会导致高度变化了但图表不刷新 + document.getElementById('main').removeAttribute('_echarts_instance_') + // 初始化k线图图表 + let chartBox = echarts.init(document.getElementById('main')) + // 直接使用pinia中储存的option数据 + const option = { + tooltip: { + trigger: 'axis', + axisPointer: { + type: 'cross' + } + }, + legend: { + data: ['日K', 'MA5', 'MA10', 'MA20', 'MA30'] + }, + grid: [{ + left: '3%', + right: '3%', + bottom: '5%', + }], + xAxis: { + type: 'category', + data: data0.categoryData, + boundaryGap: false, + axisLine: { onZero: false }, + splitLine: { show: false }, + min: 'dataMin', + max: 'dataMax' + }, + yAxis: { + scale: true, + splitArea: { + show: true + } + }, + dataZoom: [ + { + type: 'inside', + start: 50, + end: 100 + }, + { + show: true, + type: 'slider', + top: '90%', + start: 50, + end: 100 + } + ], + series: [ + { + name: '日K', + type: 'candlestick', + data: data0.values, + itemStyle: { + color: upColor, + color0: downColor, + borderColor: upBorderColor, + borderColor0: downBorderColor + }, + markPoint: { + label: { + formatter: function (param) { + return param != null ? Math.round(param.value) + '' : ''; + } + }, + data: [ + { + name: 'Mark', + coord: ['2013/5/31', 2300], + value: 2300, + itemStyle: { + color: 'rgb(41,60,85)' + } + }, + { + name: 'highest value', + type: 'max', + valueDim: 'highest' + }, + { + name: 'lowest value', + type: 'min', + valueDim: 'lowest' + }, + { + name: 'average value on close', + type: 'average', + valueDim: 'close' + } + ], + tooltip: { + formatter: function (param) { + return param.name + '<br>' + (param.data.coord || ''); + } + } + }, + markLine: { + symbol: ['none', 'none'], + data: [ + [ + { + name: 'from lowest to highest', + type: 'min', + valueDim: 'lowest', + symbol: 'circle', + symbolSize: 10, + label: { + show: false + }, + emphasis: { + label: { + show: false + } + } + }, + { + type: 'max', + valueDim: 'highest', + symbol: 'circle', + symbolSize: 10, + label: { + show: false + }, + emphasis: { + label: { + show: false + } + } + } + ], + { + name: 'min line on close', + type: 'min', + valueDim: 'close' + }, + { + name: 'max line on close', + type: 'max', + valueDim: 'close' + } + ] + } + }, + { + name: 'MA5', + type: 'line', + data: calculateMA(5), + smooth: true, + lineStyle: { + opacity: 0.5 + } + }, + { + name: 'MA10', + type: 'line', + data: calculateMA(10), + smooth: true, + lineStyle: { + opacity: 0.5 + } + }, + { + name: 'MA20', + type: 'line', + data: calculateMA(20), + smooth: true, + lineStyle: { + opacity: 0.5 + } + }, + { + name: 'MA30', + type: 'line', + data: calculateMA(30), + smooth: true, + lineStyle: { + opacity: 0.5 + } + } + ] +}; + // 配置图表数据信息 + chartBox.setOption(option) + + // mergeOptions方法可以合并两个对象,并返回合并后的对象。 + // 更新信息,可有可无?,调用时配置 + chartBox.setOption(options) + + // 图表的分组,用于联动 + chartBox.group = 'group1' + // 根据页面大小自动响应图表大小 + window.addEventListener('resize', function () { + chartBox.resize() + }) + return chartBox +} + +//绘制一个点击事件传参的Echarts图表。并返回当前图表的实例化信息,便于使用echarts.connect()进行连接 +const commonecharts = (containerId, options = {}) => { + // 先将容器中的_echarts_instance_清除,不处理会导致高度变化了但图表不刷新 + document.getElementById(containerId).removeAttribute('_echarts_instance_') + // 初始化图表 + const chart = echarts.init(document.getElementById(containerId)) + // 图表的配置信息 + const option = { + xAxis: { + type: 'category', + data: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'], + }, + yAxis: { + type: 'value', + }, + grid: { + top: '10%', + left: '3%', + right: '3%', + bottom: '20%', + }, + dataZoom: [ + { + type: 'inside', + }, + ], + series: [ + { + data: [820, 932, 901, 934, 1290, 1330, 1320], + type: 'line', + smooth: true, + }, + ], + } + // 设置图表实例的配置项 + chart.setOption(option) + // mergeOptions方法可以合并两个对象,并返回合并后的对象。 + chart.setOption(options) + + // 图表的分组,用于联动 + chart.group = 'group1' + // 根据页面大小自动响应图表大小 + window.addEventListener('resize', function () { + chartBox2.resize() + }) + return chart +} +// 连接所有图表 +echarts.connect('group1') + +onMounted(() => { + dynamicsHeight() + configecharts() +}) +onBeforeUnmount(()=>{ + echarts.disconnect() + +}) +</script> + +<template> + <div class="box"> + <div class="chartsinfo" ref="chartsInfo"> + <!-- K线图 --> + <div + id="main" + ref="mKline" + class="flex-item" + :style="{ height: `${heightList[0]}px` }" + ></div> + + <div + v-if="chartConfigs[0].status" + id="charts1" + ref="charts1" + :style="{ height: `${heightList[1]}px` }" + ></div> + <div + v-if="chartConfigs[1].status" + id="charts2" + ref="charts2" + :style="{ height: `${heightList[1]}px` }" + ></div> + <div + v-if="chartConfigs[2].status" + id="charts3" + ref="charts3" + :style="{ height: `${heightList[1]}px` }" + ></div> + <div + v-if="chartConfigs[3].status" + id="charts4" + ref="charts4" + :style="{ height: `${heightList[1]}px` }" + ></div> + <div + v-if="chartConfigs[4].status" + id="charts5" + ref="charts5" + :style="{ height: `${heightList[1]}px` }" + ></div> + </div> + + <!-- 底部的各个图表选项信息 --> + <ul class="typelist"> + <li + v-for="(item, index) in chartConfigs" + :key="index" + @click="addChart(item)" + > + {{ item.name }} + </li> + </ul> + </div> +</template> + +<style scoped> +.box { + width: 100%; + height: 100%; + display: flex; + flex-direction: column; +} +.chartsinfo { + height: calc(100vh - 20px); +} + +.typelist { + margin-top: auto; + position: relative; + z-index: 99999999; + color: #191919; + width: 100%; + font-size: 12px; + display: flex; + list-style: none; + padding: 0; +} + +.typelist > li { + padding: 2px 8px; + cursor: pointer; +} + +.active { + color: #2d98b9; +} +</style> diff --git a/src/end/EndDesign.vue b/src/end/EndDesign.vue new file mode 100644 index 0000000..bd68d51 --- /dev/null +++ b/src/end/EndDesign.vue @@ -0,0 +1,957 @@ +<script setup> +import { + onMounted, + inject, + ref, + nextTick, + onBeforeUnmount, +} from 'vue' + +import { + calculateMA, + calculateStdDeviation, + calculateMACD, + calculateKDJ, + calculateRSI, + calculateVOL, +} from './computedInfo' + +let charts1 = ref(null) +let charts2 = ref(null) +let charts3 = ref(null) +let charts4 = ref(null) + +// 请求后端数据 +let szdata = ref([]) +let kdata = ref([]) +let xdata = ref([]) +let closedata = ref([]) +let ma5 = ref() +// 标准差 +let StdDev = ref() +let topStdDev = ref() +let downStdDev = ref() + +let rsi1 = ref() +let rsi2 = ref() +let rsi3 = ref() + +let vol = ref() +let interval = ref() + +import request from '@/utils/request' +let baseURL = 'http://127.0.0.1:8015' +const redata = () => { + try { + request({ + url: baseURL + '/stock', + method: 'get', + params: { + symbol: 'sz000001', + start_date: '2021-01-01', + end_date: '2022-12-31', + }, + }).then((res) => { + xdata.value = Object.values(res.date) + let { open, close, low, high, volume } = res + for (let i = 0; i < Object.keys(open).length; i++) { + kdata.value.push([open[i], close[i], low[i], high[i]]) + closedata.value.push(close[i]) + } + + // 计算5日移动平均线 + ma5.value = calculateMA(closedata.value, 5) + + StdDev.value = calculateStdDeviation(closedata.value) + + topStdDev.value = closedata.value.map((item) => + parseFloat((item + StdDev.value).toFixed(2)) + ) + downStdDev.value = closedata.value.map((item) => + parseFloat((item - StdDev.value).toFixed(2)) + ) + + // MACD数据 + let { dif, dea, macd } = calculateMACD(closedata.value) + + // 准备数据数组,同时设置颜色 + macd = macd.map(function (value) { + return { + value: value, + itemStyle: { + color: value >= 0 ? '#FF0000' : '#00FF00', // 根据值的正负设置颜色 + }, + } + }) + + chartConfigs.value[0].options.series[0].data = dif + chartConfigs.value[0].options.series[1].data = dea + chartConfigs.value[0].options.series[2].data = macd + chartConfigs.value[0].options.xAxis.data = xdata.value + + // vol数据 + vol.value = calculateVOL(close, high, low) + chartConfigs.value[1].options.xAxis.data = xdata.value + chartConfigs.value[1].options.series[0].data = vol.value + + // KDJ数据 + let { kValues, dValues, jValues } = calculateKDJ(res) + chartConfigs.value[2].options.series[0].data = kValues + chartConfigs.value[2].options.series[1].data = dValues + chartConfigs.value[2].options.series[2].data = jValues + chartConfigs.value[2].options.xAxis.data = xdata.value + + // RSI数据 + rsi1.value = calculateRSI(closedata.value) + rsi2.value = calculateRSI(closedata.value, 12) + rsi3.value = calculateRSI(closedata.value, 24) + chartConfigs.value[3].options.series[0].data = rsi1.value + chartConfigs.value[3].options.series[1].data = rsi2.value + chartConfigs.value[3].options.series[2].data = rsi3.value + chartConfigs.value[3].options.xAxis.data = xdata.value + + dynamicsHeight() + configecharts() + }) + } catch (err) { + console.error('请求失败:', err) + } +} + +//引入echarts +let echarts = inject('echarts') + +// 外层盒子容器,为了计算图形在内部的高度分配问题 +const chartsInfo = ref(null) +// K线图的容器 +const mKline = ref(null) + +// 存储各个图形所分配的高度信息 +let heightList = ref([]) +// 计算高度、设置高度 +const dynamicsHeight = () => { + // 高度 + let domHeightList = chartsInfo.value.offsetHeight + // 判断是否进行了底部选项的点击事件,如果点击了则会往数组中添加信息,则长度就会改变 + + // if (clicklist.value.length) { + // // 先清空数组,避免 + // heightList.value = [] + // // 将处理过后的数据加入数组 + // heightList.value.push(domHeightList * (1 - clicklist.value.length * 0.15)) + // // 设置最上面K线图的高度 + // mKline.value.style.height = `${heightList.value[0]}px` + // // 设置新添加图表的高度 + // heightList.value.push(domHeightList * 0.15) + + // console.log(heightList.value) + // } else { + // // 先清空数组,避免之前的数据没有被清空 + // heightList.value = [] + + // // 设置只有K线图的高度的父容器的全部大小 + // mKline.value.style.height = `${domHeightList}px` + // } + + console.log(chartsInfo.value.children.length) + // 子元素长度 + let childrenLength = chartsInfo.value.children.length + + if (childrenLength) { + // 先清空数组,避免 + heightList.value = [] + // 将处理过后的数据加入数组 + heightList.value.push(domHeightList * (1 - childrenLength * 0.15)) + // 设置最上面K线图的高度 + mKline.value.style.height = `${heightList.value[0]}px` + // 设置新添加图表的高度 + heightList.value.push(domHeightList * 0.15) + + console.log(heightList.value) + } else { + // 先清空数组,避免之前的数据没有被清空 + heightList.value = [] + + // 设置只有K线图的高度的父容器的全部大小 + mKline.value.style.height = `${domHeightList}px` + } +} + +// 定义图表配置数组 +let chartConfigs = ref([ + { + id: 1, + name: 'MACD', + attId: 'charts1', + status: false, + options: { + animation: false, + tooltip: { + trigger: 'axis', // 触发类型为坐标轴 + axisPointer: { + // 坐标轴指示器 + type: 'cross', // 类型为交叉 + label: { + backgroundColor: '#6a7985', // 标签背景色 + }, + }, + }, + dataZoom: [ + { + type: 'inside', + }, + { + type: 'slider', + show: false, + }, + ], + xAxis: { + type: 'category', + boundaryGap: false, + data: [], + }, + yAxis: { + type: 'value', + }, + series: [ + { + name: 'DIF', + type: 'line', + itemStyle: { + normal: { + color: 'rgba(204,102,0,1)', + }, + }, + symbol: 'none', + data: [], + }, + { + name: 'DEA', + type: 'line', + itemStyle: { + normal: { + color: 'rgba(0,128,255,1)', + }, + }, + symbol: 'none', + data: [], + }, + { + name: 'MACD', + type: 'bar', + barWidth: '1', + // symbol: 'none', + data: [], + }, + ], + }, + }, + { + id: 2, + name: 'VOL', + attId: 'charts2', + status: false, + options: { + animation: false, + tooltip: { + trigger: 'axis', + axisPointer: { + type: 'cross', + label: { + backgroundColor: '#6a7985', + }, + }, + }, + dataZoom: [ + { + type: 'inside', + }, + { + type: 'slider', + show: false, + }, + ], + xAxis: { + type: 'category', + data: [], + }, + yAxis: { + type: 'value', + // splitNumber: 3 , + interval: 10, + }, + series: [ + { + name: 'VOL', + type: 'bar', + data: [], + }, + ], + }, + }, + { + id: 3, + name: 'KDJ', + attId: 'charts3', + status: false, + options: { + animation: false, + tooltip: { + trigger: 'axis', // 触发类型为坐标轴 + axisPointer: { + // 坐标轴指示器 + type: 'cross', // 类型为交叉 + label: { + backgroundColor: '#6a7985', // 标签背景色 + }, + }, + }, + dataZoom: [ + { + type: 'inside', + xAxisIndex: [0, 0], + start: 20, + end: 100, + }, + { + type: 'slider', + show: false, + }, + ], + xAxis: { + type: 'category', + boundaryGap: false, + data: [], + }, + series: [ + { + name: 'K', + type: 'line', + data: [], + symbol: 'none', + smooth: true, + // lineStyle: { + // width: 1, + // }, + // areaStyle: { + // opacity: 0.5, + // }, + // itemStyle: { + // color: 'rgba(0,128,255,1)', + // }, + }, + { + name: 'D', + type: 'line', + data: [], + symbol: 'none', + smooth: true, + // lineStyle: { + // width: 1, + // }, + // areaStyle: { + // opacity: 0.5, + // }, + // itemStyle: { + // color: 'rgba(0,128,255,1)', + // }, + }, + { + name: 'J', + type: 'line', + data: [], + symbol: 'none', + smooth: true, + // lineStyle: { + // width: 1, + // }, + // areaStyle: { + // opacity: 0.5, + // }, + // itemStyle: { + // color: 'rgba(0,128,255,1)', + // }, + }, + ], + }, + }, + { + id: 4, + name: 'RSI', + attId: 'charts4', + status: false, + options: { + animation: false, + tooltip: { + trigger: 'axis', // 触发类型为坐标轴 + axisPointer: { + // 坐标轴指示器 + type: 'cross', // 类型为交叉 + label: { + backgroundColor: '#6a7985', // 标签背景色 + }, + }, + }, + dataZoom: [ + { + type: 'inside', + xAxisIndex: [0, 0], + start: 20, + end: 100, + }, + { + type: 'slider', + show: false, + }, + ], + xAxis: { + type: 'category', + boundaryGap: false, + data: [], + }, + series: [ + { + name: 'rsi1', + type: 'line', + data: [], + symbol: 'none', + smooth: true, + // lineStyle: { + // width: 1, + // }, + // areaStyle: { + // opacity: 0.5, + // }, + // itemStyle: { + // color: 'rgba(0,128,255,1)', + // }, + }, + { + name: 'rsi2', + type: 'line', + data: [], + symbol: 'none', + smooth: true, + // lineStyle: { + // width: 1, + // }, + // areaStyle: { + // opacity: 0.5, + // }, + // itemStyle: { + // color: 'rgba(0,128,255,1)', + // }, + }, + { + name: 'rsi3', + type: 'line', + data: [], + symbol: 'none', + smooth: true, + // lineStyle: { + // width: 1, + // }, + // areaStyle: { + // opacity: 0.5, + // }, + // itemStyle: { + // color: 'rgba(0,128,255,1)', + // }, + }, + ], + }, + }, +]) + +// 储存点击底部选项的状态的数据 +const clicklist = ref([]) + +// 处理点击事件并添加图表 +const addChart = (item) => { + // 检查数组中是否已经存在具有相同domId的元素 + // let domToRemove = chartBoxList.value.find(element => element.domId === item.attId) + // if(domToRemove){ + // domToRemove.chart.dispose() + // } + + // let indexToRemove = chartBoxList.value.findIndex(element => element.domId === item.attId) + + // // 如果找到了,移除那个元素 + // if (indexToRemove !== -1) { + // chartBoxList.value.splice(indexToRemove, 1) + // } + + // 判断当前点击的图表的状态,如果已经存在则不进行操作 + if (clicklist.value.includes(item.name)) { + // 先移除当前的图表信息 + // clicklist.value = clicklist.value.filter((content) => content !== item.name) + + // if (item.attId === 'charts1') { + // charts1.value.style.display = 'none' + // } + + // 调用高度计算函数,重新分配高度 + dynamicsHeight() + // 延迟执行,确保图表已经创建 + nextTick(() => { + chartConfigs.value.forEach((element) => { + if (element.name == item.name) { + element.status = false + + // 调用configecharts函数,刷新图表,防止图形重叠 + configecharts() + } + }) + }) + } else { + // 往数组里面添加参数信息 + // clicklist.value.push(item.name) + // 遍历数组,找到对应名称的图表并设置状态为true + chartConfigs.value.forEach((element) => { + if (element.name == item.name) { + element.status = true + } + }) + + // 调用高度计算函数,重新分配高度 + dynamicsHeight() + // 延迟执行,确保图表已经创建 + nextTick(() => { + chartConfigs.value.forEach((element) => { + if (element.name == item.name) { + element.status = true + + // 调用configecharts函数,刷新图表,防止图形重叠 + configecharts() + // 调用commonecharts函数,会根据传入的参数进行图表的绘制 + // commonecharts(item.attId, item.options) + if (!clicklist.value.includes(item.name)) { + commonecharts(item.attId, item.options) + clicklist.value.push(item.name) + } + // if (item.attId === 'charts1') { + // charts1.value.style.display = 'block' + // } + } + }) + }) + } +} + +// 绘制初始的Echarts图表,始终会在页面中。并返回当前图表的实例化信息,便于使用echarts.connect()进行连接 +const configecharts = (options = {}) => { + // 先将容器中的_echarts_instance_清除,不处理会导致高度变化了但图表不刷新 + document.getElementById('main').removeAttribute('_echarts_instance_') + // 初始化k线图图表 + let chartBox = echarts.init(document.getElementById('main')) + // 直接使用pinia中储存的option数据 + const option = { + animation: false, + tooltip: { + trigger: 'axis', // 触发类型为坐标轴 + axisPointer: { + // 坐标轴指示器 + type: 'cross', // 类型为交叉 + label: { + backgroundColor: '#6a7985', // 标签背景色 + }, + animation: false, + }, + // formatter: (params)=> { + // let str = '<div style="padding: 3px 12px;width: 161px;background: #FFFFFF;border: 1px solid #DCDFE6;box-shadow:none; opacity: 1;border-radius: 4px;"><span style="color:#606062;font-size: 12px;">' + params[0].axisValue + "</span><br />"; + // params.forEach((item) => { + // str += + // '<span style="color:#f00;font-size: 12px;color: #1D1D20;"><span style="float:left; margin-top:8px; margin-right:5px;border-radius:50%;width:6px;height:6px;background-color:'+item.color+'"></span>' + " " + item.data + "</span>"; + // }); + // str += '</div>' + // return str; + + // // console.log(params[0]); + + // } + }, + legend: { + data: ['KLine', 'MA5', 'BOLL1', 'BOLL2'], + }, + grid: [ + { + left: '3%', + right: '3%', + bottom: '5%', + }, + ], + xAxis: [ + { + type: 'category', + data: xdata.value, + gridIndex: 0, + scale: true, + boundaryGap: false, + axisLine: { onZero: false }, + splitLine: { show: false }, + splitNumber: 20, + min: 'dataMin', + max: 'dataMax', + sampling: 'lttb', // 最大程度保证采样后线条的趋势,形状和极值。 + }, + ], + yAxis: [ + { + gridIndex: 0, + scale: true, + splitArea: { + show: false, + }, + }, + ], + dataZoom: [ + { + type: 'slider', + }, + { + type: 'inside', + }, + ], + series: [ + { + name: 'KLine', + type: 'candlestick', + xAxisIndex: 0, + yAxisIndex: 0, + data: kdata.value, + itemStyle: { + normal: { + color: '#ef232a', + color0: '#14b143', + borderColor: '#ef232a', + borderColor0: '#14b143', + }, + }, + // markArea: { + // silent: true, + // itemStyle: { + // normal: { + // color: 'Honeydew', + // }, + // }, + // data: [], + // }, + // markPoint: { + // data: [ + // { type: 'max', name: '最大值' }, + // { type: 'min', name: '最小值' }, + // ], + // }, + // markLine: { + // label: { + // normal: { + // position: 'middle', + // textStyle: { color: 'Blue', fontSize: 12 }, + // }, + // }, + // data: [], + // symbol: ['circle', 'none'], + // }, + }, + { + name: 'MA5', + type: 'line', + xAxisIndex: 0, + yAxisIndex: 0, + data: ma5.value, + symbol: 'none', + smooth: true, + lineStyle: { + normal: { + opacity: 0.5, + }, + }, + }, + { + name: 'BOLL1', + type: 'line', + xAxisIndex: 0, + yAxisIndex: 0, + data: topStdDev.value, + symbol: 'none', + smooth: true, + lineStyle: { + normal: { + opacity: 0.5, + color: 'red', + }, + }, + // areaStyle: { + // // 线条样式 + // normal: { + // // 右,下,左,上 + // color: new echarts.graphic.LinearGradient(0, 0, 0, 1, + // [ + // // 渐变色 + // { + // offset: 0, + // color: 'rgba(255, 46, 106, 0.21)' + // }, + // { + // offset: 1, + // color: 'rgba(255, 46, 106, 0)' + // } + // ], + // false + // ) + // } + // } + }, + { + name: 'BOLL2', + type: 'line', + xAxisIndex: 0, + yAxisIndex: 0, + data: downStdDev.value, + symbol: 'none', + smooth: true, + lineStyle: { + normal: { + opacity: 0.5, + color: 'green', + }, + }, + // areaStyle: { + // // 线条样式 + // normal: { + // // 右,下,左,上 + // color:'white' + // } + // } + }, + // { + // name: '', + // type: 'line', + // xAxisIndex: 0, + // yAxisIndex: 0, + // data: ma5.value, + // smooth: true, + // lineStyle: { + // normal: { + // opacity: 0.5, + // }, + // }, + // }, + ], + } + // 配置图表数据信息 + chartBox.setOption(option) + + // mergeOptions方法可以合并两个对象,并返回合并后的对象。 + // 更新信息,可有可无?,调用时配置 + chartBox.setOption(options) + + // 图表的分组,用于联动 + chartBox.group = 'group1' + // 根据页面大小自动响应图表大小 + window.addEventListener('resize', function () { + chartBox.resize() + }) +} + +// chart实例化数组 +let chartBoxList = ref([]) +//绘制一个点击事件传参的Echarts图表。并返回当前图表的实例化信息,便于使用echarts.connect()进行连接 +const commonecharts = (containerId, options = {}) => { + // 先将容器中的_echarts_instance_清除,不处理会导致高度变化了但图表不刷新 + document.getElementById(containerId).removeAttribute('_echarts_instance_') + // 初始化图表 + const chart = echarts.init(document.getElementById(containerId)) + + chartBoxList.value.push({ + chart, + chartid: chart.id, + domId: containerId, + }) + + console.log(chartBoxList.value) + + // 图表的配置信息 + const option = { + xAxis: { + type: 'category', + data: xdata.value, + }, + yAxis: { + type: 'value', + }, + grid: { + top: '10%', + left: '3%', + right: '3%', + bottom: '20%', + }, + dataZoom: [ + { + type: 'inside', + }, + ], + series: [ + { + data: [1, 2, 3, 4, 5, 6, 7, 2, 12, 12, 34], + type: 'line', + smooth: true, + }, + ], + } + // 设置图表实例的配置项 + chart.setOption(option) + // mergeOptions方法可以合并两个对象,并返回合并后的对象。 + chart.setOption(options) + + // 图表的分组,用于联动 + chart.group = 'group1' + + // 根据页面大小自动响应图表大小 + window.addEventListener('resize', function () { + chart.resize() + }) + + return chart +} +// 连接所有图表 +echarts.connect('group1') + +onMounted(() => { + redata() + const chart = echarts.init(charts1.value) + console.log(chart) + + charts1.value.style.height = `${200}px` + + // 图表的配置信息 + const option = { + xAxis: { + type: 'category', + data: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'], + }, + yAxis: { + type: 'value', + }, + grid: { + top: '10%', + left: '3%', + right: '3%', + bottom: '20%', + }, + dataZoom: [ + { + type: 'inside', + }, + ], + series: [ + { + data: [1, 2, 3, 4, 5, 6, 7, 2, 12, 12, 34], + type: 'line', + smooth: true, + }, + ], + } + // 设置图表实例的配置项 + chart.setOption(option) + // mergeOptions方法可以合并两个对象,并返回合并后的对象。 + // chart.setOption(options) + + // 图表的分组,用于联动 + chart.group = 'group1' + + // 根据页面大小自动响应图表大小 + window.addEventListener('resize', function () { + chart.resize() + }) + +}) +onBeforeUnmount(() => { + // echarts.disconnect() +}) +</script> + +<template> + <div class="box"> + <div class="chartsinfo" ref="chartsInfo"> + <!-- K线图 --> + <div + id="main" + ref="mKline" + class="flex-item" + :style="{ height: `${heightList[0]}px` }" + ></div> + + <div + id="charts1" + ref="charts1" + :style="{ height: `${heightList[1]}px` }" + ></div> + <!-- <div + v-if="chartConfigs[1].status" + id="charts2" + ref="charts2" + :style="{ height: `${heightList[1]}px` }" + ></div> + <div + v-if="chartConfigs[2].status" + id="charts3" + ref="charts3" + :style="{ height: `${heightList[1]}px` }" + ></div> + <div + v-if="chartConfigs[3].status" + id="charts4" + ref="charts4" + :style="{ height: `${heightList[1]}px` }" + ></div> --> + </div> + + <!-- 底部的各个图表选项信息 --> + <ul class="typelist"> + <li + v-for="(item, index) in chartConfigs" + :key="index" + @click="addChart(item)" + > + {{ item.name }} + </li> + </ul> + </div> +</template> + +<style scoped> +.box { + width: 100%; + height: 100%; + display: flex; + flex-direction: column; +} +.chartsinfo { + height: calc(100vh - 20px); +} + +.typelist { + margin-top: auto; + position: relative; + z-index: 99999999; + width: 100%; + color: #191919; + font-size: 12px; + display: flex; + list-style: none; + padding: 0; + +} +.typelist > li { + padding: 2px 8px; + cursor: pointer; +} +.typelist > li:hover { + color: gold; +} + +.active { + color: #2d98b9; +} +</style> diff --git a/src/end/NewDesign.vue b/src/end/NewDesign.vue new file mode 100644 index 0000000..1e902f5 --- /dev/null +++ b/src/end/NewDesign.vue @@ -0,0 +1,1752 @@ +<script setup> +import { + onMounted, + inject, + ref, + nextTick, + onBeforeUnmount, + computed, + watch, +} from 'vue' +import { useRouter } from 'vue-router' +const router = useRouter() + +import * as echarts from 'echarts' + +import { storeToRefs } from 'pinia' +import usethemestore from '../store/usethemestore' +const themeStore = usethemestore() +const { theme } = storeToRefs(themeStore) + +import { + calculateMA, + calculateStdDeviation, + calculateMACD, + calculateKDJ, + calculateRSI, + calculateVOL, +} from './computedInfo' + +// 图表 +let chartBox = null +let chartlistnum = ref(4) + +let charts1 = ref(null) +let initcharts1 = null +let charts1num = ref(0) +let charts2 = ref(null) +let initcharts2 = null +let charts2num = ref(0) +let charts3 = ref(null) +let initcharts3 = null +let charts3num = ref(0) +let charts4 = ref(null) +let initcharts4 = null +let charts4num = ref(0) + +// 请求后端数据 +let szdata = ref([]) +let kdata = ref([]) +let xdata = ref([]) +let closedata = ref([]) +let ma5 = ref(null) +// MACD +let dif = ref(null) +let dea = ref(null) +let macd = ref(null) + +// 标准差 +let StdDev = ref(null) +let topStdDev = ref(null) +let downStdDev = ref(null) +// KDJ +let kValues = ref(null) +let dValues = ref(null) +let jValues = ref(null) + +let rsi1 = ref(null) +let rsi2 = ref(null) +let rsi3 = ref(null) + +let vol = ref(null) +let interval = ref() + +import axios from 'axios' +let baseURL = 'http://localhost:8012/akshare' +const requestINfo = async () => { + let response = await axios({ + url: baseURL + '/kdata', + method: 'get', + }) + return response.data.message +} + +//引入echarts +// let echarts = inject('echarts') + +// 外层盒子容器,为了计算图形在内部的高度分配问题 +const chartsInfo = ref(null) +// K线图的容器 +const mKline = ref(null) + +// 存储各个图形所分配的高度信息 +let heightList = ref([]) +// 计算高度、设置高度 +const dynamicsHeight = () => { + // 高度 + let domHeightList = chartsInfo.value.offsetHeight + console.log(chartsInfo.value.children.length) + // 子元素长度 + let childrenLength = chartsInfo.value.children.length - 1 + + if (chartlistnum.value) { + // 先清空数组,避免 + heightList.value = [] + // 将处理过后的数据加入数组 + heightList.value.push(domHeightList * (1 - chartlistnum.value * 0.15)) + // 设置最上面K线图的高度 + mKline.value.style.height = `${heightList.value[0] - 10}px` + // 设置新添加图表的高度 + heightList.value.push(domHeightList * 0.15) + + console.log(heightList.value) + } else { + // 先清空数组,避免之前的数据没有被清空 + heightList.value = [] + + // 设置只有K线图的高度的父容器的全部大小 + mKline.value.style.height = `${domHeightList}px` + } +} + +// 定义图表配置数组 +let chartConfigs = ref([ + { + id: 1, + name: 'MACD', + attId: 'charts1', + status: false, + options: { + animation: false, + tooltip: { + trigger: 'axis', // 触发类型为坐标轴 + axisPointer: { + // 坐标轴指示器 + type: 'cross', // 类型为交叉 + label: { + backgroundColor: '#6a7985', // 标签背景色 + }, + }, + }, + dataZoom: [ + { + type: 'inside', + }, + { + type: 'slider', + show: false, + }, + ], + xAxis: { + type: 'category', + boundaryGap: false, + data: [], + }, + yAxis: { + type: 'value', + }, + series: [ + { + name: 'DIF', + type: 'line', + itemStyle: { + normal: { + color: 'rgba(204,102,0,1)', + }, + }, + symbol: 'none', + data: [], + }, + { + name: 'DEA', + type: 'line', + itemStyle: { + normal: { + color: 'rgba(0,128,255,1)', + }, + }, + symbol: 'none', + data: [], + }, + { + name: 'MACD', + type: 'bar', + barWidth: '1', + // symbol: 'none', + data: [], + }, + ], + }, + }, + { + id: 2, + name: 'VOL', + attId: 'charts2', + status: false, + options: { + animation: false, + tooltip: { + trigger: 'axis', + axisPointer: { + type: 'cross', + label: { + backgroundColor: '#6a7985', + }, + }, + }, + dataZoom: [ + { + type: 'inside', + }, + { + type: 'slider', + show: false, + }, + ], + xAxis: { + type: 'category', + data: [], + }, + yAxis: { + type: 'value', + // splitNumber: 3 , + interval: 10, + }, + series: [ + { + name: 'VOL', + type: 'bar', + data: [], + }, + ], + }, + }, + { + id: 3, + name: 'KDJ', + attId: 'charts3', + status: false, + options: { + animation: false, + tooltip: { + trigger: 'axis', + axisPointer: { + type: 'cross', + label: { + backgroundColor: '#6a7985', + }, + }, + }, + dataZoom: [ + { + type: 'inside', + xAxisIndex: [0, 0], + start: 20, + end: 100, + }, + { + type: 'slider', + show: false, + }, + ], + xAxis: { + type: 'category', + boundaryGap: false, + data: [], + }, + series: [ + { + name: 'K', + type: 'line', + data: [], + symbol: 'none', + smooth: true, + // lineStyle: { + // width: 1, + // }, + // areaStyle: { + // opacity: 0.5, + // }, + // itemStyle: { + // color: 'rgba(0,128,255,1)', + // }, + }, + { + name: 'D', + type: 'line', + data: [], + symbol: 'none', + smooth: true, + // lineStyle: { + // width: 1, + // }, + // areaStyle: { + // opacity: 0.5, + // }, + // itemStyle: { + // color: 'rgba(0,128,255,1)', + // }, + }, + { + name: 'J', + type: 'line', + data: [], + symbol: 'none', + smooth: true, + // lineStyle: { + // width: 1, + // }, + // areaStyle: { + // opacity: 0.5, + // }, + // itemStyle: { + // color: 'rgba(0,128,255,1)', + // }, + }, + ], + }, + }, + { + id: 4, + name: 'RSI', + attId: 'charts4', + status: false, + options: { + animation: false, + tooltip: { + trigger: 'axis', // 触发类型为坐标轴 + axisPointer: { + // 坐标轴指示器 + type: 'cross', // 类型为交叉 + label: { + backgroundColor: '#6a7985', // 标签背景色 + }, + }, + }, + dataZoom: [ + { + type: 'inside', + xAxisIndex: [0, 0], + start: 20, + end: 100, + }, + { + type: 'slider', + show: false, + }, + ], + xAxis: { + type: 'category', + boundaryGap: false, + data: [], + }, + series: [ + { + name: 'rsi1', + type: 'line', + data: [], + symbol: 'none', + smooth: true, + }, + { + name: 'rsi2', + type: 'line', + data: [], + symbol: 'none', + smooth: true, + }, + { + name: 'rsi3', + type: 'line', + data: [], + symbol: 'none', + smooth: true, + }, + ], + }, + }, +]) + +// 储存点击底部选项的状态的数据 +const clicklist = ref([]) + +// 处理点击事件并添加图表 +const addChart = (item) => { + // 卸载图表 + if (item.attId == 'charts1') { + if (!charts1num.value) { + chartlistnum.value = chartlistnum.value - 1 + initcharts1.group = '' + window.removeEventListener('resize', function () { + initcharts1.resize() + }) + initcharts1.dispose() + initcharts1 = null + + charts1.value.style.display = 'none' + + charts1num.value = 1 + } else { + chartlistnum.value = chartlistnum.value + 1 + charts1.value.style.height = `${heightList.value[1]}px` + charts1.value.style.display = 'block' + initcharts1 = echarts.init(charts1.value) + // 图表的配置信息 + let option1 = { + animation: false, + tooltip: { + trigger: 'axis', // 触发类型为坐标轴 + axisPointer: { + // 坐标轴指示器 + type: 'cross', // 类型为交叉 + label: { + backgroundColor: '#6a7985', // 标签背景色 + }, + }, + }, + grid: { + top: '10%', + left: '3%', + right: '3%', + bottom: '20%', + }, + dataZoom: [ + { + type: 'inside', + }, + { + type: 'slider', + show: false, + }, + ], + xAxis: { + type: 'category', + boundaryGap: false, + data: xdata.value, + }, + yAxis: { + type: 'value', + }, + series: [ + { + name: 'DIF', + type: 'line', + itemStyle: { + normal: { + color: 'rgba(204,102,0,1)', + }, + }, + symbol: 'none', + data: dif.value, + }, + { + name: 'DEA', + type: 'line', + itemStyle: { + normal: { + color: 'rgba(0,128,255,1)', + }, + }, + symbol: 'none', + data: dea.value, + }, + { + name: 'MACD', + type: 'bar', + barWidth: '1', + // symbol: 'none', + data: macd.value, + }, + ], + } + // 设置图表实例的配置项 + initcharts1.setOption(option1) + // 图表的分组,用于联动 + initcharts1.group = 'group1' + + // 根据页面大小自动响应图表大小 + // window.addEventListener('resize', function () { + // initcharts1.resize() + // }) + charts1num.value = 0 + } + } + if (item.attId == 'charts2') { + if (!charts2num.value) { + chartlistnum.value = chartlistnum.value - 1 + initcharts2.group = '' + window.removeEventListener('resize', function () { + initcharts2.resize() + }) + initcharts2.dispose() + initcharts2 = null + // chartsInfodom.removeChild(charts2.value) + charts2.value.style.display = 'none' + charts2num.value = 1 + } else { + chartlistnum.value = chartlistnum.value + 1 + charts2.value.style.height = `${heightList.value[1]}px` + charts2.value.style.display = 'block' + initcharts2 = echarts.init(charts2.value) + // 图表的配置信息 + let option2 = { + animation: false, + tooltip: { + trigger: 'axis', + axisPointer: { + type: 'cross', + label: { + backgroundColor: '#6a7985', + }, + }, + }, + grid: { + top: '10%', + left: '3%', + right: '3%', + bottom: '20%', + }, + dataZoom: [ + { + type: 'inside', + }, + { + type: 'slider', + show: false, + }, + ], + xAxis: { + type: 'category', + data: xdata.value, + }, + yAxis: { + type: 'value', + // splitNumber: 3 , + interval: 10, + }, + series: [ + { + name: 'VOL', + type: 'bar', + data: vol.value, + }, + ], + } + // 设置图表实例的配置项 + initcharts2.setOption(option2) + // mergeOptions方法可以合并两个对象,并返回合并后的对象。 + // chart.setOption(options) + + // 图表的分组,用于联动 + initcharts2.group = 'group1' + + // 根据页面大小自动响应图表大小 + // window.addEventListener('resize', function () { + // initcharts2.resize() + // }) + charts2num.value = 0 + } + } + if (item.attId == 'charts3') { + if (!charts3num.value) { + chartlistnum.value = chartlistnum.value - 1 + initcharts3.group = '' + window.removeEventListener('resize', function () { + initcharts3.resize() + }) + initcharts3.dispose() + initcharts3 = null + // chartsInfodom.removeChild(charts3.value) + charts3.value.style.display = 'none' + charts3num.value = 1 + } else { + chartlistnum.value = chartlistnum.value + 1 + charts3.value.style.height = `${heightList.value[1]}px` + charts3.value.style.display = 'block' + initcharts3 = echarts.init(charts3.value) + // 图表的配置信息 + let option3 = { + animation: false, + tooltip: { + trigger: 'axis', // 触发类型为坐标轴 + axisPointer: { + // 坐标轴指示器 + type: 'cross', // 类型为交叉 + label: { + backgroundColor: '#6a7985', // 标签背景色 + }, + }, + }, + grid: { + top: '10%', + left: '3%', + right: '3%', + bottom: '20%', + }, + dataZoom: [ + { + type: 'inside', + xAxisIndex: [0, 0], + start: 20, + end: 100, + }, + { + type: 'slider', + show: false, + }, + ], + xAxis: { + type: 'category', + boundaryGap: false, + data: xdata.value, + }, + yAxis: { type: 'value' }, + series: [ + { + name: 'K', + type: 'line', + data: kValues.value, + symbol: 'none', + smooth: true, + }, + { + name: 'D', + type: 'line', + data: dValues.value, + symbol: 'none', + smooth: true, + }, + { + name: 'J', + type: 'line', + data: jValues.value, + symbol: 'none', + smooth: true, + }, + ], + } + // 设置图表实例的配置项 + initcharts3.setOption(option3) + + // 图表的分组,用于联动 + initcharts3.group = 'group1' + + // 根据页面大小自动响应图表大小 + // window.addEventListener('resize', function () { + // initcharts3.resize() + // }) + charts3num.value = 0 + } + } + if (item.attId == 'charts4') { + // let chartsInfodom = chartsInfo.value + if (!charts4num.value) { + chartlistnum.value = chartlistnum.value - 1 + initcharts4.group = '' + window.removeEventListener('resize', function () { + initcharts4.resize() + }) + initcharts4.dispose() + initcharts4 = null + // chartsInfodom.removeChild(charts4.value) + charts4.value.style.display = 'none' + charts4num.value = 1 + } else { + chartlistnum.value = chartlistnum.value + 1 + charts4.value.style.height = `${heightList.value[1]}px` + charts4.value.style.display = 'block' + initcharts4 = echarts.init(charts4.value) + // 图表的配置信息 + let option4 = { + animation: false, + tooltip: { + trigger: 'axis', // 触发类型为坐标轴 + axisPointer: { + // 坐标轴指示器 + type: 'cross', // 类型为交叉 + label: { + backgroundColor: '#6a7985', // 标签背景色 + }, + }, + }, + grid: { + top: '10%', + left: '3%', + right: '3%', + bottom: '20%', + }, + dataZoom: [ + { + type: 'inside', + xAxisIndex: [0, 0], + start: 20, + end: 100, + }, + { + type: 'slider', + show: false, + }, + ], + xAxis: { + type: 'category', + boundaryGap: false, + data: xdata.value, + }, + yAxis: { type: 'value' }, + series: [ + { + name: 'rsi1', + type: 'line', + data: rsi1.value, + symbol: 'none', + smooth: true, + // lineStyle: { + // width: 1, + // }, + // areaStyle: { + // opacity: 0.5, + // }, + // itemStyle: { + // color: 'rgba(0,128,255,1)', + // }, + }, + { + name: 'rsi2', + type: 'line', + data: rsi2.value, + symbol: 'none', + smooth: true, + // lineStyle: { + // width: 1, + // }, + // areaStyle: { + // opacity: 0.5, + // }, + // itemStyle: { + // color: 'rgba(0,128,255,1)', + // }, + }, + { + name: 'rsi3', + type: 'line', + data: rsi3.value, + symbol: 'none', + smooth: true, + // lineStyle: { + // width: 1, + // }, + // areaStyle: { + // opacity: 0.5, + // }, + // itemStyle: { + // color: 'rgba(0,128,255,1)', + // }, + }, + ], + } + // 设置图表实例的配置项 + initcharts4.setOption(option4) + // mergeOptions方法可以合并两个对象,并返回合并后的对象。 + // chart.setOption(options) + + // 图表的分组,用于联动 + initcharts4.group = 'group1' + + // 根据页面大小自动响应图表大小 + // window.addEventListener('resize', function () { + // initcharts4.resize() + // }) + charts4num.value = 0 + } + } + + // 计算高度 + dynamicsHeight() + // 绘制K线图 + // configecharts() + chartBox.group = '' + window.removeEventListener('resize', function () { + chartBox.resize() + }) + chartBox.dispose() + chartBox = null + // chartsInfodom.removeChild(mKline.value) + + chartBox = echarts.init(document.getElementById('main')) + // 直接使用pinia中储存的option数据 + const option = { + animation: false, + tooltip: { + trigger: 'axis', // 触发类型为坐标轴 + axisPointer: { + // 坐标轴指示器 + type: 'cross', // 类型为交叉 + label: { + backgroundColor: '#6a7985', // 标签背景色 + }, + animation: false, + }, + }, + legend: { + data: ['KLine', 'MA5', 'BOLL1', 'BOLL2'], + }, + grid: [ + { + left: '3%', + right: '3%', + bottom: '5%', + }, + ], + xAxis: [ + { + type: 'category', + data: xdata.value, + gridIndex: 0, + scale: true, + boundaryGap: false, + axisLine: { onZero: false }, + splitLine: { show: false }, + splitNumber: 20, + min: 'dataMin', + max: 'dataMax', + sampling: 'lttb', // 最大程度保证采样后线条的趋势,形状和极值。 + }, + ], + yAxis: [ + { + gridIndex: 0, + scale: true, + splitArea: { + show: false, + }, + }, + ], + dataZoom: [ + { + type: 'slider', + }, + { + type: 'inside', + }, + ], + series: [ + { + name: 'KLine', + type: 'candlestick', + xAxisIndex: 0, + yAxisIndex: 0, + data: kdata.value, + itemStyle: { + normal: { + color: '#ef232a', + color0: '#14b143', + borderColor: '#ef232a', + borderColor0: '#14b143', + }, + }, + }, + { + name: 'MA5', + type: 'line', + xAxisIndex: 0, + yAxisIndex: 0, + data: ma5.value, + symbol: 'none', + smooth: true, + lineStyle: { + normal: { + opacity: 0.5, + }, + }, + }, + { + name: 'BOLL1', + type: 'line', + xAxisIndex: 0, + yAxisIndex: 0, + data: topStdDev.value, + symbol: 'none', + smooth: true, + lineStyle: { + normal: { + opacity: 0.5, + color: 'red', + }, + }, + }, + { + name: 'BOLL2', + type: 'line', + xAxisIndex: 0, + yAxisIndex: 0, + data: downStdDev.value, + symbol: 'none', + smooth: true, + lineStyle: { + normal: { + opacity: 0.5, + color: 'green', + }, + }, + }, + ], + } + // 配置图表数据信息 + chartBox.setOption(option) + + // 图表的分组,用于联动 + chartBox.group = 'group1' + // 根据页面大小自动响应图表大小 + window.addEventListener('resize', function () { + chartBox.resize() + }) + + console.log(chartsInfo.value.children.length) +} + +// 连接所有图表 +echarts.connect('group1') + +let res = ref({}) + +const fetchDataAndRenderChart = async () => { + try { + res.value = await requestINfo() + // 判断数据是否为空 + if (Object.keys(res.value.date).length == 0) { + console.log('没有数据') + router.push('/thenew/nodata') + return + } + + kdata.value = [] + xdata.value = [] + closedata.value = [] + ma5.value = [] + // MACD + dif.value = [] + dea.value = [] + macd.value = [] + // 标准差 + StdDev.value = [] + topStdDev.value = [] + downStdDev.value = [] + // KDJ + kValues.value = [] + dValues.value = [] + jValues.value = [] + rsi1.value = [] + rsi2.value = [] + rsi3.value = [] + vol.value = [] + + xdata.value = Object.values(res.value.date) + + let { open, close, low, high } = res.value + for (let i = 0; i < Object.keys(open).length; i++) { + kdata.value.push([open[i], close[i], low[i], high[i]]) + closedata.value.push(close[i]) + } + + // 计算5日移动平均线 + ma5.value = calculateMA(closedata.value, 5) + + StdDev.value = calculateStdDeviation(closedata.value) + + topStdDev.value = closedata.value.map((item) => + parseFloat((item + StdDev.value).toFixed(2)) + ) + downStdDev.value = closedata.value.map((item) => + parseFloat((item - StdDev.value).toFixed(2)) + ) + + // MACD数据 + // let { dif, dea, macd } = calculateMACD(closedata.value) + dif.value = calculateMACD(closedata.value).dif + dea.value = calculateMACD(closedata.value).dea + macd.value = calculateMACD(closedata.value).macd + + // 准备数据数组,同时设置颜色 + macd.value = macd.value.map(function (value) { + return { + value: value, + itemStyle: { + color: value >= 0 ? '#FF0000' : '#00FF00', // 根据值的正负设置颜色 + }, + } + }) + + chartConfigs.value[0].options.series[0].data = dif.value + chartConfigs.value[0].options.series[1].data = dea.value + chartConfigs.value[0].options.series[2].data = macd.value + chartConfigs.value[0].options.xAxis.data = xdata.value + + // vol数据 + vol.value = calculateVOL(close, high, low) + chartConfigs.value[1].options.xAxis.data = xdata.value + chartConfigs.value[1].options.series[0].data = vol.value + + // KDJ数据 + // let { kValues, dValues, jValues } = calculateKDJ(res.value) + kValues.value = calculateKDJ(res.value).kValues + dValues.value = calculateKDJ(res.value).dValues + jValues.value = calculateKDJ(res.value).jValues + + chartConfigs.value[2].options.series[0].data = kValues.value + chartConfigs.value[2].options.series[1].data = dValues.value + chartConfigs.value[2].options.series[2].data = jValues.value + chartConfigs.value[2].options.xAxis.data = xdata.value + + // RSI数据 + rsi1.value = calculateRSI(closedata.value) + rsi2.value = calculateRSI(closedata.value, 12) + rsi3.value = calculateRSI(closedata.value, 24) + chartConfigs.value[3].options.series[0].data = rsi1.value + chartConfigs.value[3].options.series[1].data = rsi2.value + chartConfigs.value[3].options.series[2].data = rsi3.value + chartConfigs.value[3].options.xAxis.data = xdata.value + + // 计算高度 + dynamicsHeight() + // 绘制K线图 + // configecharts() + } catch (error) { + console.log(error) + } +} + + + + +onMounted(async () => { + // 初始数据请求 + await fetchDataAndRenderChart() + + // --------------------------初始化k线图图表--------------------- + // 先将容器中的_echarts_instance_清除,不处理会导致高度变化了但图表不刷新 + document.getElementById('main').removeAttribute('_echarts_instance_') + chartBox = echarts.init(document.getElementById('main')) + // 直接使用pinia中储存的option数据 + let option = { + animation: false, + tooltip: { + trigger: 'axis', // 触发类型为坐标轴 + axisPointer: { + // 坐标轴指示器 + type: 'cross', // 类型为交叉 + label: { + backgroundColor: '#6a7985', // 标签背景色 + }, + animation: false, + }, + }, + legend: { + data: ['KLine', 'MA5', 'BOLL1', 'BOLL2'], + textStyle: { + color: '#fff', + fontSize: 12, + }, + }, + grid: [ + { + left: '3%', + right: '3%', + bottom: '10%', + top: '12%', + }, + ], + xAxis: [ + { + type: 'category', + data: xdata.value, + gridIndex: 0, + scale: true, + boundaryGap: false, + axisLine: { onZero: false }, + splitLine: { show: false }, + splitNumber: 20, + min: 'dataMin', + max: 'dataMax', + sampling: 'lttb', // 最大程度保证采样后线条的趋势,形状和极值。 + }, + ], + yAxis: [ + { + gridIndex: 0, + scale: true, + splitArea: { + show: false, + }, + splitLine: { + lineStyle: { + color: 'white', + opacity: 0.1, + }, + }, + }, + ], + dataZoom: [ + { + type: 'slider', + }, + { + type: 'inside', + }, + ], + series: [ + { + name: 'KLine', + type: 'candlestick', + xAxisIndex: 0, + yAxisIndex: 0, + data: kdata.value, + itemStyle: { + normal: { + color: '#ef232a', + color0: '#14b143', + borderColor: '#ef232a', + borderColor0: '#14b143', + }, + }, + }, + { + name: 'MA5', + type: 'line', + xAxisIndex: 0, + yAxisIndex: 0, + data: ma5.value, + symbol: 'none', + smooth: true, + lineStyle: { + normal: { + opacity: 0.8, + width: 2, + }, + }, + }, + { + name: 'BOLL1', + type: 'line', + xAxisIndex: 0, + yAxisIndex: 0, + data: topStdDev.value, + symbol: 'none', + smooth: true, + lineStyle: { + normal: { + opacity: 0.5, + color: 'red', + }, + }, + }, + { + name: 'BOLL2', + type: 'line', + xAxisIndex: 0, + yAxisIndex: 0, + data: downStdDev.value, + symbol: 'none', + smooth: true, + lineStyle: { + normal: { + opacity: 0.5, + color: 'green', + }, + }, + }, + ], + } + if(!theme.value){ + option.legend.textStyle.color = '#fff' + option.yAxis[0].splitLine.lineStyle.color = '#fff' + option.yAxis[0].splitLine.lineStyle.opacity = 0.1 + } + if(theme.value){ + option.legend.textStyle.color = '#000' + option.yAxis[0].splitLine.lineStyle.color = 'rgb(168, 168, 168)' + option.yAxis[0].splitLine.lineStyle.opacity = 0.4 + } + + + // 配置图表数据信息 + chartBox.setOption(option) + + // 图表的分组,用于联动 + chartBox.group = 'group1' + // 根据页面大小自动响应图表大小 + window.addEventListener('resize', function(){ + chartBox.resize() + }) + + // -------------------------MACD------------------------------- + charts1.value.style.height = `${heightList.value[1]}px` + initcharts1 = echarts.init(charts1.value) + // 图表的配置信息 + let option1 = { + animation: false, + tooltip: { + trigger: 'axis', // 触发类型为坐标轴 + axisPointer: { + // 坐标轴指示器 + type: 'cross', // 类型为交叉 + label: { + backgroundColor: '#6a7985', // 标签背景色 + }, + }, + }, + grid: { + top: '10%', + left: '3%', + right: '3%', + bottom: '20%', + }, + dataZoom: [ + { + type: 'inside', + }, + { + type: 'slider', + show: false, + }, + ], + xAxis: { + type: 'category', + boundaryGap: false, + data: xdata.value, + }, + yAxis: [{ + type: 'value', + splitLine: { + lineStyle: { + color: 'white', + opacity: 0.1, + }, + }, + }], + series: [ + { + name: 'DIF', + type: 'line', + itemStyle: { + normal: { + color: 'rgba(204,102,0,1)', + }, + }, + symbol: 'none', + data: dif.value, + }, + { + name: 'DEA', + type: 'line', + itemStyle: { + normal: { + color: 'rgba(0,128,255,1)', + }, + }, + symbol: 'none', + data: dea.value, + }, + { + name: 'MACD', + type: 'bar', + barWidth: '1', + // symbol: 'none', + data: macd.value, + }, + ], + } + if(!theme.value){ + option1.yAxis[0].splitLine.lineStyle.color = '#fff' + option1.yAxis[0].splitLine.lineStyle.opacity = 0.1 + } + if(theme.value){ + option1.yAxis[0].splitLine.lineStyle.color = 'rgb(168, 168, 168)' + option1.yAxis[0].splitLine.lineStyle.opacity = 0.4 + } + + + // 设置图表实例的配置项 + initcharts1.setOption(option1) + + // 图表的分组,用于联动 + initcharts1.group = 'group1' + + // 根据页面大小自动响应图表大小 + window.addEventListener('resize', function(){ + initcharts1.resize() + }) + // -------------------------------------------------------- + + // ------------------------VOL-------------------------------- + charts2.value.style.height = `${heightList.value[1]}px` + initcharts2 = echarts.init(charts2.value) + // 图表的配置信息 + let option2 = { + animation: false, + tooltip: { + trigger: 'axis', + axisPointer: { + type: 'cross', + label: { + backgroundColor: '#6a7985', + }, + }, + }, + grid: { + top: '10%', + left: '3%', + right: '3%', + bottom: '20%', + }, + dataZoom: [ + { + type: 'inside', + }, + { + type: 'slider', + show: false, + }, + ], + xAxis: { + type: 'category', + data: xdata.value, + }, + yAxis: [{ + type: 'value', + // splitNumber: 3 , + interval: 10, + splitLine: { + lineStyle: { + color: 'white', + opacity: 0.1, + }, + }, + }], + series: [ + { + name: 'VOL', + type: 'bar', + data: vol.value, + }, + ], + } + + if(!theme.value){ + option2.yAxis[0].splitLine.lineStyle.color = '#fff' + option2.yAxis[0].splitLine.lineStyle.opacity = 0.1 + } + if(theme.value){ + option2.yAxis[0].splitLine.lineStyle.color = 'rgb(168, 168, 168)' + option2.yAxis[0].splitLine.lineStyle.opacity = 0.4 + } + + // 设置图表实例的配置项 + initcharts2.setOption(option2) + // 图表的分组,用于联动 + initcharts2.group = 'group1' + + // 根据页面大小自动响应图表大小 + window.addEventListener('resize', function(){ + initcharts2.resize() + }) + // -------------------------------------------------------- + + // -----------------------KDJ--------------------------------- + charts3.value.style.height = `${heightList.value[1]}px` + initcharts3 = echarts.init(charts3.value) + // 图表的配置信息 + let option3 = { + animation: false, + tooltip: { + trigger: 'axis', // 触发类型为坐标轴 + axisPointer: { + // 坐标轴指示器 + type: 'cross', // 类型为交叉 + label: { + backgroundColor: '#6a7985', // 标签背景色 + }, + }, + }, + grid: { + top: '10%', + left: '3%', + right: '3%', + bottom: '20%', + }, + dataZoom: [ + { + type: 'inside', + xAxisIndex: [0, 0], + start: 20, + end: 100, + }, + { + type: 'slider', + show: false, + }, + ], + xAxis: { + type: 'category', + boundaryGap: false, + data: xdata.value, + }, + yAxis: [{ + type: 'value', + splitLine: { + lineStyle: { + color: 'white', + opacity: 0.1, + }, + }, + }], + series: [ + { + name: 'K', + type: 'line', + data: kValues.value, + symbol: 'none', + smooth: true, + lineStyle: { + width: 1, // 设置线条宽度为5 + }, + }, + { + name: 'D', + type: 'line', + data: dValues.value, + symbol: 'none', + smooth: true, + lineStyle: { + width: 1, // 设置线条宽度为5 + }, + }, + { + name: 'J', + type: 'line', + data: jValues.value, + symbol: 'none', + smooth: true, + lineStyle: { + width: 1, // 设置线条宽度为5 + }, + }, + ], + } + + if(!theme.value){ + option3.yAxis[0].splitLine.lineStyle.color = '#fff' + option3.yAxis[0].splitLine.lineStyle.opacity = 0.1 + } + if(theme.value){ + option3.yAxis[0].splitLine.lineStyle.color = 'rgb(168, 168, 168)' + option3.yAxis[0].splitLine.lineStyle.opacity = 0.4 + } + // 设置图表实例的配置项 + initcharts3.setOption(option3) + + // 图表的分组,用于联动 + initcharts3.group = 'group1' + + // 根据页面大小自动响应图表大小 + window.addEventListener('resize', function(){ + initcharts3.resize() + }) + // -------------------------------------------------------- + + // ----------------------RSI---------------------------------- + charts4.value.style.height = `${heightList.value[1]}px` + initcharts4 = echarts.init(charts4.value) + // 图表的配置信息 + let option4 = { + animation: false, + tooltip: { + trigger: 'axis', // 触发类型为坐标轴 + axisPointer: { + // 坐标轴指示器 + type: 'cross', // 类型为交叉 + label: { + backgroundColor: '#6a7985', // 标签背景色 + }, + }, + }, + grid: { + top: '10%', + left: '3%', + right: '3%', + bottom: '20%', + }, + dataZoom: [ + { + type: 'inside', + xAxisIndex: [0, 0], + start: 20, + end: 100, + }, + { + type: 'slider', + show: false, + }, + ], + xAxis: { + type: 'category', + boundaryGap: false, + data: xdata.value, + }, + yAxis: [{ + type: 'value', + splitLine: { + lineStyle: { + color: 'white', + opacity: 0.1, + }, + }, + }], + series: [ + { + name: 'rsi1', + type: 'line', + data: rsi1.value, + symbol: 'none', + smooth: true, + lineStyle: { + width: 1, // 设置线条宽度为5 + }, + }, + { + name: 'rsi2', + type: 'line', + data: rsi2.value, + symbol: 'none', + smooth: true, + lineStyle: { + width: 1, // 设置线条宽度为5 + }, + }, + { + name: 'rsi3', + type: 'line', + data: rsi3.value, + symbol: 'none', + smooth: true, + lineStyle: { + width: 1, // 设置线条宽度为5 + }, + }, + ], + } + + if(!theme.value){ + option4.yAxis[0].splitLine.lineStyle.color = '#fff' + option4.yAxis[0].splitLine.lineStyle.opacity = 0.1 + } + if(theme.value){ + option4.yAxis[0].splitLine.lineStyle.color = 'rgb(168, 168, 168)' + option4.yAxis[0].splitLine.lineStyle.opacity = 0.4 + } + // 设置图表实例的配置项 + initcharts4.setOption(option4) + // 图表的分组,用于联动 + initcharts4.group = 'group1' + + // 根据页面大小自动响应图表大小 + window.addEventListener('resize', function(){ + initcharts4.resize() + }) + + watch( + () => theme.value, + async (news, old) => { + await nextTick() + console.log(news) + + if (news === false) { + try{ + option.legend.textStyle.color = '#fff' + option.yAxis[0].splitLine.lineStyle.color = '#fff' + option.yAxis[0].splitLine.lineStyle.opacity = 0.1 + + option1.yAxis[0].splitLine.lineStyle.color = '#fff' + option1.yAxis[0].splitLine.lineStyle.opacity = 0.1 + + option2.yAxis[0].splitLine.lineStyle.color = '#fff' + option2.yAxis[0].splitLine.lineStyle.opacity = 0.1 + + option3.yAxis[0].splitLine.lineStyle.color = '#fff' + option3.yAxis[0].splitLine.lineStyle.opacity = 0.1 + + option4.yAxis[0].splitLine.lineStyle.color = '#fff' + option4.yAxis[0].splitLine.lineStyle.opacity = 0.1 + + chartBox.setOption(option) + initcharts1.setOption(option1) + initcharts2.setOption(option2) + initcharts3.setOption(option3) + initcharts4.setOption(option4) + }catch(err){} + } + if (news === true) { + + try{ + option.legend.textStyle.color = '#000' + option.yAxis[0].splitLine.lineStyle.color = 'rgb(168, 168, 168)' + option.yAxis[0].splitLine.lineStyle.opacity = 0.4 + + option1.yAxis[0].splitLine.lineStyle.color = 'rgb(168, 168, 168)' + option1.yAxis[0].splitLine.lineStyle.opacity = 0.4 + + option2.yAxis[0].splitLine.lineStyle.color = 'rgb(168, 168, 168)' + option2.yAxis[0].splitLine.lineStyle.opacity = 0.4 + + option3.yAxis[0].splitLine.lineStyle.color = 'rgb(168, 168, 168)' + option3.yAxis[0].splitLine.lineStyle.opacity = 0.4 + + option4.yAxis[0].splitLine.lineStyle.color = 'rgb(168, 168, 168)' + option4.yAxis[0].splitLine.lineStyle.opacity = 0.4 + + chartBox.setOption(option) + initcharts1.setOption(option1) + initcharts2.setOption(option2) + initcharts3.setOption(option3) + initcharts4.setOption(option4) + }catch(err){} + } + } + ) + + +}) +// 在组件销毁时清除定时器 +onBeforeUnmount(() => { + if (chartBox) { + window.removeEventListener('resize', function(){ + chartBox.resize() + }) + chartBox.dispose() // 销毁 ECharts 实例 + chartBox = null // 手动释放引用 + } + if (initcharts1) { + window.removeEventListener('resize', function(){ + initcharts1.resize() + }) + initcharts1.dispose() + initcharts1 = null + } + if (initcharts2) { + window.removeEventListener('resize', function(){ + initcharts2.resize() + }) + initcharts2.dispose() + initcharts2 = null + } + if (initcharts3) { + window.removeEventListener('resize', function(){ + initcharts3.resize() + }) + initcharts3.dispose() + initcharts3 = null + } + if (initcharts4) { + window.removeEventListener('resize', function(){ + initcharts4.resize() + }) + initcharts4.dispose() + initcharts4 = null + } +}) +</script> + +<template> + <div class="box"> + <div class="chartsinfo" ref="chartsInfo"> + <!-- K线图 --> + <div + id="main" + ref="mKline" + class="flex-item" + :style="{ height: `${heightList[0]}px` }" + ></div> + + <div + id="charts1" + ref="charts1" + :style="{ height: `${heightList[1]}px` }" + ></div> + <div + id="charts2" + ref="charts2" + :style="{ height: `${heightList[1]}px` }" + ></div> + <div + id="charts3" + ref="charts3" + :style="{ height: `${heightList[1]}px` }" + ></div> + <div + id="charts4" + ref="charts4" + :style="{ height: `${heightList[1]}px` }" + ></div> + </div> + + <!-- 底部的各个图表选项信息 --> + <ul class="typelist"> + <li + v-for="(item, index) in chartConfigs" + :key="index" + @click="addChart(item)" + > + {{ item.name }} + </li> + </ul> + </div> +</template> + +<style scoped> +.box { + width: 100%; + height: 100%; + display: flex; + flex-direction: column; + background-color: var(--my-common-bgc-2) !important; +} +.chartsinfo { + min-height: calc(100vh - 52px); + box-sizing: border-box; +} + +.typelist { + margin-top: auto; + position: relative; + z-index: 99; + width: 100%; + /* color: #414040; */ + background-color: var(--my-common-bgc-2) !important; + color: var(--my-common-fc-1); + font-size: 12px; + display: flex; + list-style: none; + padding: 0; +} + +.typelist > li { + padding: 2px 8px; + cursor: pointer; +} +.typelist > li:hover { + color: gold; +} + +.active { + color: #2d98b9; +} +</style> diff --git a/src/end/NodataView.vue b/src/end/NodataView.vue new file mode 100644 index 0000000..3a6cc33 --- /dev/null +++ b/src/end/NodataView.vue @@ -0,0 +1,32 @@ +<script setup></script> + +<template> + <div class="con"> + <div class="nodata"> + <div class="text">当前股票没有数据!</div> + </div> + </div> +</template> +<style scoped> +.con { + width: 100%; + height: 100%; + background-color: var(--my-common-bgc-2); +} +.nodata { + min-height: calc(100vh - 50px); + /* height: calc(100vh - 22px); */ + display: flex; + flex-direction: column; + justify-content: center; + align-items: center; +} +.text{ + font-size: 30px; + font-weight: bold; + /*字体粗细*/ + -webkit-text-stroke: 1px var(--my-common-fc-1); + /*描边*/ + -webkit-text-fill-color: transparent; +} +</style> \ No newline at end of file diff --git a/src/end/computedInfo.js b/src/end/computedInfo.js new file mode 100644 index 0000000..f842f9a --- /dev/null +++ b/src/end/computedInfo.js @@ -0,0 +1,293 @@ +// 计算移动平均线MA的函数,接收收盘价格数组和计算所需的天数作为参数 +export function calculateMA (closingPrices, dayCount) { + // 检查数据点的数量是否足够计算移动平均线 + if (closingPrices.length < dayCount) { + return null // 数据不足,返回null + } + + let result = [] + // 从第dayCount个数据点开始计算(因为前dayCount-1个数据点不足以计算一个完整的移动平均线) + for (let i = 0; i <= closingPrices.length - dayCount; i++) { + let sum = 0 + // 计算当前窗口内所有价格的总和 + for (let j = 0; j < dayCount; j++) { + sum += closingPrices[i + j] + } + // 计算并添加移动平均线值到结果数组 + result.push(sum / dayCount) + } + result = result.map(item => parseFloat(item.toFixed(2))) + return result // 返回计算出的移动平均线值数组 +} + +// 计算标准差的函数 +export function calculateStdDeviation (prices) { + if (prices.length === 0) { + throw new Error("价格数组不能为空") + } + // 计算平均值 + const mean = prices.reduce((sum, price) => sum + price, 0) / prices.length + + // 计算每个价格与平均值的差的平方和 + const varianceSum = prices.reduce((sum, price) => sum + Math.pow(price - mean, 2), 0) + + // 计算方差(样本方差使用N-1作为分母) + const variance = varianceSum / (prices.length - 1) + + // 计算标准差(方差的平方根),取两位小数 + const stDeviation = parseFloat(Math.sqrt(variance).toFixed(2)) + + return stDeviation +} + + +export function calculateEMA (prices, period) { + let ema = [] + let multiplier = 2 / (period + 1) + let previousEMA = prices.reduce((sum, price) => sum + price, 0) / period // 初始EMA为前period天的收盘价平均值 + + ema.push(previousEMA) // 添加第一个EMA值 + + for (let i = period; i < prices.length; i++) { + let currentEMA = (prices[i] - previousEMA) * multiplier + previousEMA + ema.push(currentEMA) + previousEMA = currentEMA + } + + // 我们只关心最后一个EMA值(即最新周期的EMA),但这里返回整个EMA数组以便调试 + return ema +} + + +// 计算DIF的函数,但dif数组长度将受限于价格数组和EMA计算所需的最小长度 +export function calculateDIF (prices, shortPeriod, longPeriod) { + // 确保价格数组足够长以计算所需的EMA + if (prices.length < longPeriod + 1) { + return [] // 或抛出错误 + } + + // 计算整个价格数组的EMA,但通常只关注最近的EMA值 + let shortEMA = calculateEMA(prices, shortPeriod) + let longEMA = calculateEMA(prices, longPeriod) + + // DIF数组,从两个EMA数组都有值的起始位置开始计算 + let dif = [] + let startIndex = Math.max(shortEMA.length - 1, longEMA.length - 1) - (longPeriod - 1) // 找到两个EMA都能计算的起始索引(可能需要根据实际情况调整) + // 注意:这里的startIndex计算可能需要根据实际需求进行调整,因为它依赖于EMA数组的实际可用长度和所需的计算周期。 + // 下面的循环确保了只有当两个EMA数组在相同索引处都有值时,才计算DIF。 + for (let i = startIndex; i < Math.min(shortEMA.length, longEMA.length); i++) { + dif.push(shortEMA[i] - longEMA[i]) + } + + // 如果需要,可以在dif数组前面填充null或0,以使其长度与prices相同(但这在金融分析上可能没有意义) + // while (dif.length < prices.length) { + // dif.unshift(null); // 或0,或其他适当的填充值 + // } + + return dif // 返回DIF数组,其长度可能小于prices数组 +} +// 计算DEA的函数 +export function calculateDEA (dif, deaPeriod) { + // DEA就是DIF的EMA,所以直接使用calculateEMA函数计算DIF数组的EMA + return calculateEMA(dif, deaPeriod) +} + +// MACD指标的计算函数 +export function calculateMACD ( + prices, + shortPeriod = 12, + longPeriod = 26, + deaPeriod = 9 +) { + function calculateEMA (prices, period) { + let ema = [] + let multiplier = 2 / (period + 1) + let sum = 0 + for (let i = 0; i < period; i++) { + sum += prices[i] + } + let previousEMA = sum / period + ema.push(previousEMA) + for (let i = period; i < prices.length; i++) { + let currentEMA = (prices[i] - previousEMA) * multiplier + previousEMA + ema.push(currentEMA) + previousEMA = currentEMA + } + return ema + } + + let shortEMA = calculateEMA(prices, shortPeriod) + let longEMA = calculateEMA(prices, longPeriod) + let dif = [] + for (let i = 0; i < Math.min(shortEMA.length, longEMA.length); i++) { + dif.push(shortEMA[i] - longEMA[i]) + } + let dea = calculateEMA(dif, deaPeriod) + let macd = [] + for (let i = 0; i < Math.min(dif.length, dea.length); i++) { + macd.push((dif[i] - dea[i]) * 2) + } + // 将dif, dea, macd中的值保留两位小数 + dif = dif.map((item) => parseFloat(item.toFixed(2))) + dea = dea.map((item) => parseFloat(item.toFixed(2))) + macd = macd.map((item) => parseFloat(item.toFixed(2))) + return { + dif, + dea, + macd + } +} + + + + +// ----------------------------计算KDJ指标的函数---------------------------- +// 数据整理 +export function changeShape (res) { + // 获取对象的键(这里我们知道键是 'date', 'low', 'high', 'close',但为了通用性,我们还是获取所有键) + const keys = Object.keys(res) + + // 初始化一个空数组来存储结果 + let result = [] + + // 假设所有对象的属性(date, low, high, close)都有相同的索引范围 + // 这里我们取第一个对象的键集合来确定索引范围(假设它们都有0和1这两个键) + const indexRange = Object.keys(res.date) // 或者使用任何其他对象的键集合,因为它们应该有相同的索引 + + // 遍历索引范围 + for (let index of indexRange) { + // 将索引转换为数字类型,以便进行数学运算(虽然在这个例子中它们已经是数字字符串) + const numIndex = parseInt(index, 10) + + // 收集对应索引的值到一个子数组中 + const row = [ + res.date[numIndex], + res.low[numIndex], + res.high[numIndex], + res.close[numIndex] + ] + + // 将子数组添加到结果数组中 + result.push(row) + } + return result +} +// 计算函数 +export function calculateKDJ (prices) { + + prices = changeShape(prices) + let lows = [] + let highs = [] + let closes = [] + // 提取最低价、最高价、收盘价数组 + prices.forEach((price) => { + lows.push(price[1]) + highs.push(price[2]) + closes.push(price[3]) + }) + let kValues = [] + let dValues = [] + let jValues = [] + let period = 9 // 默认的计算周期,可以根据实际情况调整 + for (let i = 0; i < closes.length; i++) { + if (i < period - 1) { + kValues.push(10) + dValues.push(10) + jValues.push(10) + continue + } + // 计算RSV值(未成熟随机值) + let lowPeriod = Math.min(...lows.slice(i - period + 1, i + 1)) + let highPeriod = Math.max(...highs.slice(i - period + 1, i + 1)) + let rsv = ((closes[i] - lowPeriod) / (highPeriod - lowPeriod)) * 100 + if (i === period - 1) { + kValues.push(rsv) + dValues.push(rsv) + } else { + // 计算K值,一般采用加权移动平均的方式,这里简化为前一日K值的2/3加上今日RSV的1/3 + let k = (2 / 3) * kValues[i - 1] + (1 / 3) * rsv + kValues.push(k) + // 计算D值,一般是前一日D值的2/3加上今日K值的1/3 + let d = (2 / 3) * dValues[i - 1] + (1 / 3) * k + dValues.push(d) + } + // 计算J值,一般公式为3*K - 2*D + let j = 3 * kValues[i] - 2 * dValues[i] + jValues.push(j) + } + kValues = kValues.map(item => parseFloat(item.toFixed(2))) + dValues = dValues.map(item => parseFloat(item.toFixed(2))) + jValues = jValues.map(item => parseFloat(item.toFixed(2))) + return { + kValues, + dValues, + jValues + } +} +// ------------------------------------------------------------------- + +// ----------------------------计算RSI指标的函数---------------------------- +// RSI 的时间跨度推荐 6、12、24 三个值,6 日近似一周的时间周期,12 日可以看作半个月的时间跨度,而 24 日约为一个月的时间跨度。 +// 短期 RSI 对于价格的变化情况反应比较灵敏,RSI 的值波动较大;长期 RSI 值反应相对迟钝,其波动相对较小。 +export function calculateRSI (closePrices, period = 6) { + let gains = [] + let losses = [] + let rsi = [] + + for (let i = 0; i < closePrices.length; i++) { + if (i === 0) { + gains.push(0) + losses.push(0) + } else { + let diff = closePrices[i] - closePrices[i - 1] + if (diff > 0) { + gains.push(diff) + losses.push(0) + } else { + gains.push(0) + losses.push(Math.abs(diff)) + } + } + + if (i >= period - 1) { + let sumGain = 0 + let sumLoss = 0 + for (let j = i - (period - 1); j <= i; j++) { + sumGain += gains[j] + sumLoss += losses[j] + } + + let avgGain = sumGain / period + let avgLoss = sumLoss / period + let rs = avgGain / avgLoss + rsi.push(100 - (100 / (1 + rs))) + } + } + rsi = rsi.map(item => parseFloat(item.toFixed(2))) + return rsi +} + +// ----------------------------计算VOL指标的函数---------------------------- + +export function calculateVOL (close, high, low) { + let arr = [] + let volvalues = Object.values(close) + let highvalues = Object.values(high) + let lowvalues = Object.values(low) + + for (let i = 0; i < volvalues.length; i++) { + let change = (highvalues[i] + lowvalues[i]) / 2 + arr.push({ + value: volvalues[i], + itemStyle: { + color: volvalues[i] >= change ? '#FF0000' : '#00FF00' // 根据值的正负设置颜色 + } + }) + } + + return arr +} + + + + diff --git a/src/endnew/NewStyleDesign.vue b/src/endnew/NewStyleDesign.vue new file mode 100644 index 0000000..2aec231 --- /dev/null +++ b/src/endnew/NewStyleDesign.vue @@ -0,0 +1,1767 @@ +<script setup> +import { + onMounted, + inject, + ref, + nextTick, + onBeforeUnmount, + computed, + watch, +} from 'vue' +import { useRouter } from 'vue-router' +const router = useRouter() + +import * as echarts from 'echarts' + +import { storeToRefs } from 'pinia' +import usethemestore from '../store/usethemestore' +const themeStore = usethemestore() +const { theme } = storeToRefs(themeStore) + +import { + calculateMA, + calculateStdDeviation, + calculateMACD, + calculateKDJ, + calculateRSI, + calculateVOL, +} from '../end/computedInfo' + +// 图表 +let chartBox = null +let chartlistnum = ref(4) + +let charts1 = ref(null) +let initcharts1 = null +let charts1num = ref(0) +let charts2 = ref(null) +let initcharts2 = null +let charts2num = ref(0) +let charts3 = ref(null) +let initcharts3 = null +let charts3num = ref(0) +let charts4 = ref(null) +let initcharts4 = null +let charts4num = ref(0) + +// 请求后端数据 +let szdata = ref([]) +let kdata = ref([]) +let xdata = ref([]) +let closedata = ref([]) +let ma5 = ref(null) +// MACD +let dif = ref(null) +let dea = ref(null) +let macd = ref(null) + +// 标准差 +let StdDev = ref(null) +let topStdDev = ref(null) +let downStdDev = ref(null) +// KDJ +let kValues = ref(null) +let dValues = ref(null) +let jValues = ref(null) + +let rsi1 = ref(null) +let rsi2 = ref(null) +let rsi3 = ref(null) + +let vol = ref(null) +let interval = ref() + +import axios from 'axios' +let baseURL = 'http://localhost:8012/akshare' +const requestINfo = async () => { + let response = await axios({ + url: baseURL + '/kdata', + method: 'get', + }) + return response.data.message +} + +//引入echarts +// let echarts = inject('echarts') + +// 外层盒子容器,为了计算图形在内部的高度分配问题 +const chartsInfo = ref(null) +// K线图的容器 +const mKline = ref(null) + +// 存储各个图形所分配的高度信息 +let heightList = ref([]) +// 计算高度、设置高度 +const dynamicsHeight = () => { + // 高度 + let domHeightList = chartsInfo.value.offsetHeight + console.log(chartsInfo.value.children.length) + // 子元素长度 + let childrenLength = chartsInfo.value.children.length - 1 + + if (chartlistnum.value) { + // 先清空数组,避免 + heightList.value = [] + // 将处理过后的数据加入数组 + heightList.value.push(domHeightList * (1 - chartlistnum.value * 0.15)) + // 设置最上面K线图的高度 + mKline.value.style.height = `${heightList.value[0] - 10}px` + // 设置新添加图表的高度 + heightList.value.push(domHeightList * 0.15) + + console.log(heightList.value) + } else { + // 先清空数组,避免之前的数据没有被清空 + heightList.value = [] + + // 设置只有K线图的高度的父容器的全部大小 + mKline.value.style.height = `${domHeightList}px` + } +} + +// 定义图表配置数组 +let chartConfigs = ref([ + { + id: 1, + name: 'MACD', + attId: 'charts1', + status: false, + options: { + animation: false, + tooltip: { + trigger: 'axis', // 触发类型为坐标轴 + axisPointer: { + // 坐标轴指示器 + type: 'cross', // 类型为交叉 + label: { + backgroundColor: '#6a7985', // 标签背景色 + }, + }, + }, + dataZoom: [ + { + type: 'inside', + }, + { + type: 'slider', + show: false, + }, + ], + xAxis: { + type: 'category', + boundaryGap: false, + data: [], + }, + yAxis: { + type: 'value', + }, + series: [ + { + name: 'DIF', + type: 'line', + itemStyle: { + normal: { + color: 'rgba(204,102,0,1)', + }, + }, + symbol: 'none', + data: [], + }, + { + name: 'DEA', + type: 'line', + itemStyle: { + normal: { + color: 'rgba(0,128,255,1)', + }, + }, + symbol: 'none', + data: [], + }, + { + name: 'MACD', + type: 'bar', + barWidth: '1', + // symbol: 'none', + data: [], + }, + ], + }, + }, + { + id: 2, + name: 'VOL', + attId: 'charts2', + status: false, + options: { + animation: false, + tooltip: { + trigger: 'axis', + axisPointer: { + type: 'cross', + label: { + backgroundColor: '#6a7985', + }, + }, + }, + dataZoom: [ + { + type: 'inside', + }, + { + type: 'slider', + show: false, + }, + ], + xAxis: { + type: 'category', + data: [], + }, + yAxis: { + type: 'value', + // splitNumber: 3 , + interval: 10, + }, + series: [ + { + name: 'VOL', + type: 'bar', + data: [], + }, + ], + }, + }, + { + id: 3, + name: 'KDJ', + attId: 'charts3', + status: false, + options: { + animation: false, + tooltip: { + trigger: 'axis', + axisPointer: { + type: 'cross', + label: { + backgroundColor: '#6a7985', + }, + }, + }, + dataZoom: [ + { + type: 'inside', + xAxisIndex: [0, 0], + start: 20, + end: 100, + }, + { + type: 'slider', + show: false, + }, + ], + xAxis: { + type: 'category', + boundaryGap: false, + data: [], + }, + series: [ + { + name: 'K', + type: 'line', + data: [], + symbol: 'none', + smooth: true, + // lineStyle: { + // width: 1, + // }, + // areaStyle: { + // opacity: 0.5, + // }, + // itemStyle: { + // color: 'rgba(0,128,255,1)', + // }, + }, + { + name: 'D', + type: 'line', + data: [], + symbol: 'none', + smooth: true, + // lineStyle: { + // width: 1, + // }, + // areaStyle: { + // opacity: 0.5, + // }, + // itemStyle: { + // color: 'rgba(0,128,255,1)', + // }, + }, + { + name: 'J', + type: 'line', + data: [], + symbol: 'none', + smooth: true, + // lineStyle: { + // width: 1, + // }, + // areaStyle: { + // opacity: 0.5, + // }, + // itemStyle: { + // color: 'rgba(0,128,255,1)', + // }, + }, + ], + }, + }, + { + id: 4, + name: 'RSI', + attId: 'charts4', + status: false, + options: { + animation: false, + tooltip: { + trigger: 'axis', // 触发类型为坐标轴 + axisPointer: { + // 坐标轴指示器 + type: 'cross', // 类型为交叉 + label: { + backgroundColor: '#6a7985', // 标签背景色 + }, + }, + }, + dataZoom: [ + { + type: 'inside', + xAxisIndex: [0, 0], + start: 20, + end: 100, + }, + { + type: 'slider', + show: false, + }, + ], + xAxis: { + type: 'category', + boundaryGap: false, + data: [], + }, + series: [ + { + name: 'rsi1', + type: 'line', + data: [], + symbol: 'none', + smooth: true, + }, + { + name: 'rsi2', + type: 'line', + data: [], + symbol: 'none', + smooth: true, + }, + { + name: 'rsi3', + type: 'line', + data: [], + symbol: 'none', + smooth: true, + }, + ], + }, + }, +]) + +// 储存点击底部选项的状态的数据 +const clicklist = ref([]) + +// 处理点击事件并添加图表 +const addChart = (item) => { + // 卸载图表 + if (item.attId == 'charts1') { + if (!charts1num.value) { + chartlistnum.value = chartlistnum.value - 1 + initcharts1.group = '' + window.removeEventListener('resize', function () { + initcharts1.resize() + }) + initcharts1.dispose() + initcharts1 = null + + charts1.value.style.display = 'none' + + charts1num.value = 1 + } else { + chartlistnum.value = chartlistnum.value + 1 + charts1.value.style.height = `${heightList.value[1]}px` + charts1.value.style.display = 'block' + initcharts1 = echarts.init(charts1.value) + // 图表的配置信息 + let option1 = { + animation: false, + tooltip: { + trigger: 'axis', // 触发类型为坐标轴 + axisPointer: { + // 坐标轴指示器 + type: 'cross', // 类型为交叉 + label: { + backgroundColor: '#6a7985', // 标签背景色 + }, + }, + }, + grid: { + top: '10%', + left: '3%', + right: '3%', + bottom: '20%', + }, + dataZoom: [ + { + type: 'inside', + }, + { + type: 'slider', + show: false, + }, + ], + xAxis: { + type: 'category', + boundaryGap: false, + data: xdata.value, + }, + yAxis: { + type: 'value', + }, + series: [ + { + name: 'DIF', + type: 'line', + itemStyle: { + normal: { + color: 'rgba(204,102,0,1)', + }, + }, + symbol: 'none', + data: dif.value, + }, + { + name: 'DEA', + type: 'line', + itemStyle: { + normal: { + color: 'rgba(0,128,255,1)', + }, + }, + symbol: 'none', + data: dea.value, + }, + { + name: 'MACD', + type: 'bar', + barWidth: '1', + // symbol: 'none', + data: macd.value, + }, + ], + } + // 设置图表实例的配置项 + initcharts1.setOption(option1) + // 图表的分组,用于联动 + initcharts1.group = 'group1' + + // 根据页面大小自动响应图表大小 + // window.addEventListener('resize', function () { + // initcharts1.resize() + // }) + charts1num.value = 0 + } + } + if (item.attId == 'charts2') { + if (!charts2num.value) { + chartlistnum.value = chartlistnum.value - 1 + initcharts2.group = '' + window.removeEventListener('resize', function () { + initcharts2.resize() + }) + initcharts2.dispose() + initcharts2 = null + // chartsInfodom.removeChild(charts2.value) + charts2.value.style.display = 'none' + charts2num.value = 1 + } else { + chartlistnum.value = chartlistnum.value + 1 + charts2.value.style.height = `${heightList.value[1]}px` + charts2.value.style.display = 'block' + initcharts2 = echarts.init(charts2.value) + // 图表的配置信息 + let option2 = { + animation: false, + tooltip: { + trigger: 'axis', + axisPointer: { + type: 'cross', + label: { + backgroundColor: '#6a7985', + }, + }, + }, + grid: { + top: '10%', + left: '3%', + right: '3%', + bottom: '20%', + }, + dataZoom: [ + { + type: 'inside', + }, + { + type: 'slider', + show: false, + }, + ], + xAxis: { + type: 'category', + data: xdata.value, + }, + yAxis: { + type: 'value', + // splitNumber: 3 , + interval: 10, + }, + series: [ + { + name: 'VOL', + type: 'bar', + data: vol.value, + }, + ], + } + // 设置图表实例的配置项 + initcharts2.setOption(option2) + // mergeOptions方法可以合并两个对象,并返回合并后的对象。 + // chart.setOption(options) + + // 图表的分组,用于联动 + initcharts2.group = 'group1' + + // 根据页面大小自动响应图表大小 + // window.addEventListener('resize', function () { + // initcharts2.resize() + // }) + charts2num.value = 0 + } + } + if (item.attId == 'charts3') { + if (!charts3num.value) { + chartlistnum.value = chartlistnum.value - 1 + initcharts3.group = '' + window.removeEventListener('resize', function () { + initcharts3.resize() + }) + initcharts3.dispose() + initcharts3 = null + // chartsInfodom.removeChild(charts3.value) + charts3.value.style.display = 'none' + charts3num.value = 1 + } else { + chartlistnum.value = chartlistnum.value + 1 + charts3.value.style.height = `${heightList.value[1]}px` + charts3.value.style.display = 'block' + initcharts3 = echarts.init(charts3.value) + // 图表的配置信息 + let option3 = { + animation: false, + tooltip: { + trigger: 'axis', // 触发类型为坐标轴 + axisPointer: { + // 坐标轴指示器 + type: 'cross', // 类型为交叉 + label: { + backgroundColor: '#6a7985', // 标签背景色 + }, + }, + }, + grid: { + top: '10%', + left: '3%', + right: '3%', + bottom: '20%', + }, + dataZoom: [ + { + type: 'inside', + xAxisIndex: [0, 0], + start: 20, + end: 100, + }, + { + type: 'slider', + show: false, + }, + ], + xAxis: { + type: 'category', + boundaryGap: false, + data: xdata.value, + }, + yAxis: { type: 'value' }, + series: [ + { + name: 'K', + type: 'line', + data: kValues.value, + symbol: 'none', + smooth: true, + }, + { + name: 'D', + type: 'line', + data: dValues.value, + symbol: 'none', + smooth: true, + }, + { + name: 'J', + type: 'line', + data: jValues.value, + symbol: 'none', + smooth: true, + }, + ], + } + // 设置图表实例的配置项 + initcharts3.setOption(option3) + + // 图表的分组,用于联动 + initcharts3.group = 'group1' + + // 根据页面大小自动响应图表大小 + // window.addEventListener('resize', function () { + // initcharts3.resize() + // }) + charts3num.value = 0 + } + } + if (item.attId == 'charts4') { + // let chartsInfodom = chartsInfo.value + if (!charts4num.value) { + chartlistnum.value = chartlistnum.value - 1 + initcharts4.group = '' + window.removeEventListener('resize', function () { + initcharts4.resize() + }) + initcharts4.dispose() + initcharts4 = null + // chartsInfodom.removeChild(charts4.value) + charts4.value.style.display = 'none' + charts4num.value = 1 + } else { + chartlistnum.value = chartlistnum.value + 1 + charts4.value.style.height = `${heightList.value[1]}px` + charts4.value.style.display = 'block' + initcharts4 = echarts.init(charts4.value) + // 图表的配置信息 + let option4 = { + animation: false, + tooltip: { + trigger: 'axis', // 触发类型为坐标轴 + axisPointer: { + // 坐标轴指示器 + type: 'cross', // 类型为交叉 + label: { + backgroundColor: '#6a7985', // 标签背景色 + }, + }, + }, + grid: { + top: '10%', + left: '3%', + right: '3%', + bottom: '20%', + }, + dataZoom: [ + { + type: 'inside', + xAxisIndex: [0, 0], + start: 20, + end: 100, + }, + { + type: 'slider', + show: false, + }, + ], + xAxis: { + type: 'category', + boundaryGap: false, + data: xdata.value, + }, + yAxis: { type: 'value' }, + series: [ + { + name: 'rsi1', + type: 'line', + data: rsi1.value, + symbol: 'none', + smooth: true, + // lineStyle: { + // width: 1, + // }, + // areaStyle: { + // opacity: 0.5, + // }, + // itemStyle: { + // color: 'rgba(0,128,255,1)', + // }, + }, + { + name: 'rsi2', + type: 'line', + data: rsi2.value, + symbol: 'none', + smooth: true, + // lineStyle: { + // width: 1, + // }, + // areaStyle: { + // opacity: 0.5, + // }, + // itemStyle: { + // color: 'rgba(0,128,255,1)', + // }, + }, + { + name: 'rsi3', + type: 'line', + data: rsi3.value, + symbol: 'none', + smooth: true, + // lineStyle: { + // width: 1, + // }, + // areaStyle: { + // opacity: 0.5, + // }, + // itemStyle: { + // color: 'rgba(0,128,255,1)', + // }, + }, + ], + } + // 设置图表实例的配置项 + initcharts4.setOption(option4) + // mergeOptions方法可以合并两个对象,并返回合并后的对象。 + // chart.setOption(options) + + // 图表的分组,用于联动 + initcharts4.group = 'group1' + + // 根据页面大小自动响应图表大小 + // window.addEventListener('resize', function () { + // initcharts4.resize() + // }) + charts4num.value = 0 + } + } + + // 计算高度 + // dynamicsHeight() + // 绘制K线图 + // configecharts() + chartBox.group = '' + window.removeEventListener('resize', function () { + chartBox.resize() + }) + chartBox.dispose() + chartBox = null + // chartsInfodom.removeChild(mKline.value) + + chartBox = echarts.init(document.getElementById('main')) + // 直接使用pinia中储存的option数据 + const option = { + animation: false, + tooltip: { + trigger: 'axis', // 触发类型为坐标轴 + axisPointer: { + // 坐标轴指示器 + type: 'cross', // 类型为交叉 + label: { + backgroundColor: '#6a7985', // 标签背景色 + }, + animation: false, + }, + }, + legend: { + data: ['KLine', 'MA5', 'BOLL1', 'BOLL2'], + }, + grid: [ + { + left: '3%', + right: '3%', + bottom: '5%', + }, + ], + xAxis: [ + { + type: 'category', + data: xdata.value, + gridIndex: 0, + scale: true, + boundaryGap: false, + axisLine: { onZero: false }, + splitLine: { show: false }, + splitNumber: 20, + min: 'dataMin', + max: 'dataMax', + sampling: 'lttb', // 最大程度保证采样后线条的趋势,形状和极值。 + }, + ], + yAxis: [ + { + gridIndex: 0, + scale: true, + splitArea: { + show: false, + }, + }, + ], + dataZoom: [ + { + type: 'slider', + }, + { + type: 'inside', + }, + ], + series: [ + { + name: 'KLine', + type: 'candlestick', + xAxisIndex: 0, + yAxisIndex: 0, + data: kdata.value, + itemStyle: { + normal: { + color: '#ef232a', + color0: '#14b143', + borderColor: '#ef232a', + borderColor0: '#14b143', + }, + }, + }, + { + name: 'MA5', + type: 'line', + xAxisIndex: 0, + yAxisIndex: 0, + data: ma5.value, + symbol: 'none', + smooth: true, + lineStyle: { + normal: { + opacity: 0.5, + }, + }, + }, + { + name: 'BOLL1', + type: 'line', + xAxisIndex: 0, + yAxisIndex: 0, + data: topStdDev.value, + symbol: 'none', + smooth: true, + lineStyle: { + normal: { + opacity: 0.5, + color: 'red', + }, + }, + }, + { + name: 'BOLL2', + type: 'line', + xAxisIndex: 0, + yAxisIndex: 0, + data: downStdDev.value, + symbol: 'none', + smooth: true, + lineStyle: { + normal: { + opacity: 0.5, + color: 'green', + }, + }, + }, + ], + } + // 配置图表数据信息 + chartBox.setOption(option) + + // 图表的分组,用于联动 + chartBox.group = 'group1' + // 根据页面大小自动响应图表大小 + window.addEventListener('resize', function () { + chartBox.resize() + }) + + console.log(chartsInfo.value.children.length) +} + +// 连接所有图表 +echarts.connect('group1') + +let res = ref({}) + +const fetchDataAndRenderChart = async () => { + try { + res.value = await requestINfo() + // 判断数据是否为空 + if (Object.keys(res.value.date).length == 0) { + console.log('没有数据') + router.push('/thenew/nodata') + return + } + + kdata.value = [] + xdata.value = [] + closedata.value = [] + ma5.value = [] + // MACD + dif.value = [] + dea.value = [] + macd.value = [] + // 标准差 + StdDev.value = [] + topStdDev.value = [] + downStdDev.value = [] + // KDJ + kValues.value = [] + dValues.value = [] + jValues.value = [] + rsi1.value = [] + rsi2.value = [] + rsi3.value = [] + vol.value = [] + + xdata.value = Object.values(res.value.date) + + let { open, close, low, high } = res.value + for (let i = 0; i < Object.keys(open).length; i++) { + kdata.value.push([open[i], close[i], low[i], high[i]]) + closedata.value.push(close[i]) + } + + // 计算5日移动平均线 + ma5.value = calculateMA(closedata.value, 5) + + StdDev.value = calculateStdDeviation(closedata.value) + + topStdDev.value = closedata.value.map((item) => + parseFloat((item + StdDev.value).toFixed(2)) + ) + downStdDev.value = closedata.value.map((item) => + parseFloat((item - StdDev.value).toFixed(2)) + ) + + // MACD数据 + // let { dif, dea, macd } = calculateMACD(closedata.value) + dif.value = calculateMACD(closedata.value).dif + dea.value = calculateMACD(closedata.value).dea + macd.value = calculateMACD(closedata.value).macd + + // 准备数据数组,同时设置颜色 + macd.value = macd.value.map(function (value) { + return { + value: value, + itemStyle: { + color: value >= 0 ? '#FF0000' : '#00FF00', // 根据值的正负设置颜色 + }, + } + }) + + chartConfigs.value[0].options.series[0].data = dif.value + chartConfigs.value[0].options.series[1].data = dea.value + chartConfigs.value[0].options.series[2].data = macd.value + chartConfigs.value[0].options.xAxis.data = xdata.value + + // vol数据 + vol.value = calculateVOL(close, high, low) + chartConfigs.value[1].options.xAxis.data = xdata.value + chartConfigs.value[1].options.series[0].data = vol.value + + // KDJ数据 + // let { kValues, dValues, jValues } = calculateKDJ(res.value) + kValues.value = calculateKDJ(res.value).kValues + dValues.value = calculateKDJ(res.value).dValues + jValues.value = calculateKDJ(res.value).jValues + + chartConfigs.value[2].options.series[0].data = kValues.value + chartConfigs.value[2].options.series[1].data = dValues.value + chartConfigs.value[2].options.series[2].data = jValues.value + chartConfigs.value[2].options.xAxis.data = xdata.value + + // RSI数据 + rsi1.value = calculateRSI(closedata.value) + rsi2.value = calculateRSI(closedata.value, 12) + rsi3.value = calculateRSI(closedata.value, 24) + chartConfigs.value[3].options.series[0].data = rsi1.value + chartConfigs.value[3].options.series[1].data = rsi2.value + chartConfigs.value[3].options.series[2].data = rsi3.value + chartConfigs.value[3].options.xAxis.data = xdata.value + + // 计算高度 + // dynamicsHeight() + // 绘制K线图 + // configecharts() + } catch (error) { + console.log(error) + } +} + + + + +onMounted(async () => { + // 初始数据请求 + await fetchDataAndRenderChart() + + // --------------------------初始化k线图图表--------------------- + // 先将容器中的_echarts_instance_清除,不处理会导致高度变化了但图表不刷新 + document.getElementById('main').removeAttribute('_echarts_instance_') + chartBox = echarts.init(document.getElementById('main')) + // 直接使用pinia中储存的option数据 + let option = { + animation: false, + tooltip: { + trigger: 'axis', // 触发类型为坐标轴 + axisPointer: { + // 坐标轴指示器 + type: 'cross', // 类型为交叉 + label: { + backgroundColor: '#6a7985', // 标签背景色 + }, + animation: false, + }, + }, + legend: { + data: ['KLine', 'MA5', 'BOLL1', 'BOLL2'], + textStyle: { + color: '#fff', + fontSize: 12, + }, + }, + grid: [ + { + left: '3%', + right: '3%', + bottom: '10%', + top: '12%', + }, + ], + xAxis: [ + { + type: 'category', + data: xdata.value, + gridIndex: 0, + scale: true, + boundaryGap: false, + axisLine: { onZero: false }, + splitLine: { show: false }, + splitNumber: 20, + min: 'dataMin', + max: 'dataMax', + sampling: 'lttb', // 最大程度保证采样后线条的趋势,形状和极值。 + }, + ], + yAxis: [ + { + gridIndex: 0, + scale: true, + splitArea: { + show: false, + }, + splitLine: { + lineStyle: { + color: 'white', + opacity: 0.1, + }, + }, + }, + ], + dataZoom: [ + { + type: 'slider', + }, + { + type: 'inside', + }, + ], + series: [ + { + name: 'KLine', + type: 'candlestick', + xAxisIndex: 0, + yAxisIndex: 0, + data: kdata.value, + itemStyle: { + normal: { + color: '#ef232a', + color0: '#14b143', + borderColor: '#ef232a', + borderColor0: '#14b143', + }, + }, + }, + { + name: 'MA5', + type: 'line', + xAxisIndex: 0, + yAxisIndex: 0, + data: ma5.value, + symbol: 'none', + smooth: true, + lineStyle: { + normal: { + opacity: 0.8, + width: 2, + }, + }, + }, + { + name: 'BOLL1', + type: 'line', + xAxisIndex: 0, + yAxisIndex: 0, + data: topStdDev.value, + symbol: 'none', + smooth: true, + lineStyle: { + normal: { + opacity: 0.5, + color: 'red', + }, + }, + }, + { + name: 'BOLL2', + type: 'line', + xAxisIndex: 0, + yAxisIndex: 0, + data: downStdDev.value, + symbol: 'none', + smooth: true, + lineStyle: { + normal: { + opacity: 0.5, + color: 'green', + }, + }, + }, + ], + } + if(!theme.value){ + option.legend.textStyle.color = '#fff' + option.yAxis[0].splitLine.lineStyle.color = '#fff' + option.yAxis[0].splitLine.lineStyle.opacity = 0.1 + } + if(theme.value){ + option.legend.textStyle.color = '#000' + option.yAxis[0].splitLine.lineStyle.color = 'rgb(168, 168, 168)' + option.yAxis[0].splitLine.lineStyle.opacity = 0.4 + } + + + // 配置图表数据信息 + chartBox.setOption(option) + + // 图表的分组,用于联动 + chartBox.group = 'group1' + // 根据页面大小自动响应图表大小 + window.addEventListener('resize', function(){ + chartBox.resize() + }) + + // -------------------------MACD------------------------------- + charts1.value.style.height = `${heightList.value[1]}px` + initcharts1 = echarts.init(charts1.value) + // 图表的配置信息 + let option1 = { + animation: false, + tooltip: { + trigger: 'axis', // 触发类型为坐标轴 + axisPointer: { + // 坐标轴指示器 + type: 'cross', // 类型为交叉 + label: { + backgroundColor: '#6a7985', // 标签背景色 + }, + }, + }, + grid: { + top: '10%', + left: '3%', + right: '3%', + bottom: '20%', + }, + dataZoom: [ + { + type: 'inside', + }, + { + type: 'slider', + show: false, + }, + ], + xAxis: { + type: 'category', + boundaryGap: false, + data: xdata.value, + }, + yAxis: [{ + type: 'value', + splitLine: { + lineStyle: { + color: 'white', + opacity: 0.1, + }, + }, + }], + series: [ + { + name: 'DIF', + type: 'line', + itemStyle: { + normal: { + color: 'rgba(204,102,0,1)', + }, + }, + symbol: 'none', + data: dif.value, + }, + { + name: 'DEA', + type: 'line', + itemStyle: { + normal: { + color: 'rgba(0,128,255,1)', + }, + }, + symbol: 'none', + data: dea.value, + }, + { + name: 'MACD', + type: 'bar', + barWidth: '1', + // symbol: 'none', + data: macd.value, + }, + ], + } + if(!theme.value){ + option1.yAxis[0].splitLine.lineStyle.color = '#fff' + option1.yAxis[0].splitLine.lineStyle.opacity = 0.1 + } + if(theme.value){ + option1.yAxis[0].splitLine.lineStyle.color = 'rgb(168, 168, 168)' + option1.yAxis[0].splitLine.lineStyle.opacity = 0.4 + } + + + // 设置图表实例的配置项 + initcharts1.setOption(option1) + + // 图表的分组,用于联动 + initcharts1.group = 'group1' + + // 根据页面大小自动响应图表大小 + window.addEventListener('resize', function(){ + initcharts1.resize() + }) + // -------------------------------------------------------- + + // ------------------------VOL-------------------------------- + charts2.value.style.height = `${heightList.value[1]}px` + initcharts2 = echarts.init(charts2.value) + // 图表的配置信息 + let option2 = { + animation: false, + tooltip: { + trigger: 'axis', + axisPointer: { + type: 'cross', + label: { + backgroundColor: '#6a7985', + }, + }, + }, + grid: { + top: '10%', + left: '3%', + right: '3%', + bottom: '20%', + }, + dataZoom: [ + { + type: 'inside', + }, + { + type: 'slider', + show: false, + }, + ], + xAxis: { + type: 'category', + data: xdata.value, + }, + yAxis: [{ + type: 'value', + // splitNumber: 3 , + interval: 10, + splitLine: { + lineStyle: { + color: 'white', + opacity: 0.1, + }, + }, + }], + series: [ + { + name: 'VOL', + type: 'bar', + data: vol.value, + }, + ], + } + + if(!theme.value){ + option2.yAxis[0].splitLine.lineStyle.color = '#fff' + option2.yAxis[0].splitLine.lineStyle.opacity = 0.1 + } + if(theme.value){ + option2.yAxis[0].splitLine.lineStyle.color = 'rgb(168, 168, 168)' + option2.yAxis[0].splitLine.lineStyle.opacity = 0.4 + } + + // 设置图表实例的配置项 + initcharts2.setOption(option2) + // 图表的分组,用于联动 + initcharts2.group = 'group1' + + // 根据页面大小自动响应图表大小 + window.addEventListener('resize', function(){ + initcharts2.resize() + }) + // -------------------------------------------------------- + + // -----------------------KDJ--------------------------------- + charts3.value.style.height = `${heightList.value[1]}px` + initcharts3 = echarts.init(charts3.value) + // 图表的配置信息 + let option3 = { + animation: false, + tooltip: { + trigger: 'axis', // 触发类型为坐标轴 + axisPointer: { + // 坐标轴指示器 + type: 'cross', // 类型为交叉 + label: { + backgroundColor: '#6a7985', // 标签背景色 + }, + }, + }, + grid: { + top: '10%', + left: '3%', + right: '3%', + bottom: '20%', + }, + dataZoom: [ + { + type: 'inside', + xAxisIndex: [0, 0], + start: 20, + end: 100, + }, + { + type: 'slider', + show: false, + }, + ], + xAxis: { + type: 'category', + boundaryGap: false, + data: xdata.value, + }, + yAxis: [{ + type: 'value', + splitLine: { + lineStyle: { + color: 'white', + opacity: 0.1, + }, + }, + }], + series: [ + { + name: 'K', + type: 'line', + data: kValues.value, + symbol: 'none', + smooth: true, + lineStyle: { + width: 1, // 设置线条宽度为5 + }, + }, + { + name: 'D', + type: 'line', + data: dValues.value, + symbol: 'none', + smooth: true, + lineStyle: { + width: 1, // 设置线条宽度为5 + }, + }, + { + name: 'J', + type: 'line', + data: jValues.value, + symbol: 'none', + smooth: true, + lineStyle: { + width: 1, // 设置线条宽度为5 + }, + }, + ], + } + + if(!theme.value){ + option3.yAxis[0].splitLine.lineStyle.color = '#fff' + option3.yAxis[0].splitLine.lineStyle.opacity = 0.1 + } + if(theme.value){ + option3.yAxis[0].splitLine.lineStyle.color = 'rgb(168, 168, 168)' + option3.yAxis[0].splitLine.lineStyle.opacity = 0.4 + } + // 设置图表实例的配置项 + initcharts3.setOption(option3) + + // 图表的分组,用于联动 + initcharts3.group = 'group1' + + // 根据页面大小自动响应图表大小 + window.addEventListener('resize', function(){ + initcharts3.resize() + }) + // -------------------------------------------------------- + + // ----------------------RSI---------------------------------- + charts4.value.style.height = `${heightList.value[1]}px` + initcharts4 = echarts.init(charts4.value) + // 图表的配置信息 + let option4 = { + animation: false, + tooltip: { + trigger: 'axis', // 触发类型为坐标轴 + axisPointer: { + // 坐标轴指示器 + type: 'cross', // 类型为交叉 + label: { + backgroundColor: '#6a7985', // 标签背景色 + }, + }, + }, + grid: { + top: '10%', + left: '3%', + right: '3%', + bottom: '20%', + }, + dataZoom: [ + { + type: 'inside', + xAxisIndex: [0, 0], + start: 20, + end: 100, + }, + { + type: 'slider', + show: false, + }, + ], + xAxis: { + type: 'category', + boundaryGap: false, + data: xdata.value, + }, + yAxis: [{ + type: 'value', + splitLine: { + lineStyle: { + color: 'white', + opacity: 0.1, + }, + }, + }], + series: [ + { + name: 'rsi1', + type: 'line', + data: rsi1.value, + symbol: 'none', + smooth: true, + lineStyle: { + width: 1, // 设置线条宽度为5 + }, + }, + { + name: 'rsi2', + type: 'line', + data: rsi2.value, + symbol: 'none', + smooth: true, + lineStyle: { + width: 1, // 设置线条宽度为5 + }, + }, + { + name: 'rsi3', + type: 'line', + data: rsi3.value, + symbol: 'none', + smooth: true, + lineStyle: { + width: 1, // 设置线条宽度为5 + }, + }, + ], + } + + if(!theme.value){ + option4.yAxis[0].splitLine.lineStyle.color = '#fff' + option4.yAxis[0].splitLine.lineStyle.opacity = 0.1 + } + if(theme.value){ + option4.yAxis[0].splitLine.lineStyle.color = 'rgb(168, 168, 168)' + option4.yAxis[0].splitLine.lineStyle.opacity = 0.4 + } + // 设置图表实例的配置项 + initcharts4.setOption(option4) + // 图表的分组,用于联动 + initcharts4.group = 'group1' + + // 根据页面大小自动响应图表大小 + window.addEventListener('resize', function(){ + initcharts4.resize() + }) + + watch( + () => theme.value, + async (news, old) => { + await nextTick() + console.log(news) + + if (news === false) { + try{ + option.legend.textStyle.color = '#fff' + option.yAxis[0].splitLine.lineStyle.color = '#fff' + option.yAxis[0].splitLine.lineStyle.opacity = 0.1 + + option1.yAxis[0].splitLine.lineStyle.color = '#fff' + option1.yAxis[0].splitLine.lineStyle.opacity = 0.1 + + option2.yAxis[0].splitLine.lineStyle.color = '#fff' + option2.yAxis[0].splitLine.lineStyle.opacity = 0.1 + + option3.yAxis[0].splitLine.lineStyle.color = '#fff' + option3.yAxis[0].splitLine.lineStyle.opacity = 0.1 + + option4.yAxis[0].splitLine.lineStyle.color = '#fff' + option4.yAxis[0].splitLine.lineStyle.opacity = 0.1 + + chartBox.setOption(option) + initcharts1.setOption(option1) + initcharts2.setOption(option2) + initcharts3.setOption(option3) + initcharts4.setOption(option4) + }catch(err){} + } + if (news === true) { + + try{ + option.legend.textStyle.color = '#000' + option.yAxis[0].splitLine.lineStyle.color = 'rgb(168, 168, 168)' + option.yAxis[0].splitLine.lineStyle.opacity = 0.4 + + option1.yAxis[0].splitLine.lineStyle.color = 'rgb(168, 168, 168)' + option1.yAxis[0].splitLine.lineStyle.opacity = 0.4 + + option2.yAxis[0].splitLine.lineStyle.color = 'rgb(168, 168, 168)' + option2.yAxis[0].splitLine.lineStyle.opacity = 0.4 + + option3.yAxis[0].splitLine.lineStyle.color = 'rgb(168, 168, 168)' + option3.yAxis[0].splitLine.lineStyle.opacity = 0.4 + + option4.yAxis[0].splitLine.lineStyle.color = 'rgb(168, 168, 168)' + option4.yAxis[0].splitLine.lineStyle.opacity = 0.4 + + chartBox.setOption(option) + initcharts1.setOption(option1) + initcharts2.setOption(option2) + initcharts3.setOption(option3) + initcharts4.setOption(option4) + }catch(err){} + } + } + ) + + +}) +// 在组件销毁时清除定时器 +onBeforeUnmount(() => { + if (chartBox) { + window.removeEventListener('resize', function(){ + chartBox.resize() + }) + chartBox.dispose() // 销毁 ECharts 实例 + chartBox = null // 手动释放引用 + } + if (initcharts1) { + window.removeEventListener('resize', function(){ + initcharts1.resize() + }) + initcharts1.dispose() + initcharts1 = null + } + if (initcharts2) { + window.removeEventListener('resize', function(){ + initcharts2.resize() + }) + initcharts2.dispose() + initcharts2 = null + } + if (initcharts3) { + window.removeEventListener('resize', function(){ + initcharts3.resize() + }) + initcharts3.dispose() + initcharts3 = null + } + if (initcharts4) { + window.removeEventListener('resize', function(){ + initcharts4.resize() + }) + initcharts4.dispose() + initcharts4 = null + } +}) +</script> + +<template> + <div class="box"> + <div class="chartsinfo" ref="chartsInfo"> + <div class="newk"> + <!-- K线图 --> + <div + id="main" + ref="mKline" + class="flex-item" + :style="{ height: `100%` }" + ></div> + </div> + + <div class="newd"> + <div + id="charts1" + ref="charts1" + ></div> + <div + id="charts2" + ref="charts2" + ></div> + <div + id="charts3" + ref="charts3" + ></div> + <div + id="charts4" + ref="charts4" + ></div> + </div> + </div> + + <!-- 底部的各个图表选项信息 --> + <!-- <ul class="typelist"> + <li + v-for="(item, index) in chartConfigs" + :key="index" + @click="addChart(item)" + > + {{ item.name }} + </li> + </ul> --> + </div> +</template> + +<style scoped> +.box { + width: 100%; + height: 100%; + display: flex; + flex-direction: column; + background-color: var(--my-common-bgc-2) !important; +} +.chartsinfo { + height: 100%; + min-height: calc(100vh - 52px); + box-sizing: border-box; + display: flex; + flex-direction: column; + +} +.newk{ + flex: 2; + border: 1px solid rgb(190, 187, 187); +} +.newd{ + flex: 2; + /* border: 1px solid rgb(240, 33, 147); */ + display: grid; + grid-template-columns: repeat(2, 1fr); + grid-template-rows: repeat(2, 1fr); +} + +.typelist { + margin-top: auto; + position: relative; + z-index: 99; + width: 100%; + /* color: #414040; */ + background-color: var(--my-common-bgc-2) !important; + color: var(--my-common-fc-1); + font-size: 12px; + display: flex; + list-style: none; + padding: 0; +} + +.typelist > li { + padding: 2px 8px; + cursor: pointer; +} +.typelist > li:hover { + color: gold; +} + +.active { + color: #2d98b9; +} +</style> diff --git a/src/endtype/HourLineWrapper.vue b/src/endtype/HourLineWrapper.vue new file mode 100644 index 0000000..ea20766 --- /dev/null +++ b/src/endtype/HourLineWrapper.vue @@ -0,0 +1,32 @@ +<template> + <component :is="currentComponent" /> +</template> + +<script> +import { defineComponent, computed } from 'vue'; +import { useRoute } from 'vue-router'; +import NewDesign from '@/end/NewDesign.vue'; +import NewStyleDesign from '@/endnew/NewStyleDesign.vue'; +import NodataView from '@/end/NodataView.vue'; + +export default defineComponent({ + setup() { + const route = useRoute(); + + const currentComponent = computed(() => { + // 根据路由参数动态加载组件 + if (route.params.type === 'vertical') { + return NewDesign; + } else if (route.params.type === 'grid') { + return NewStyleDesign; + } + // 默认加载的组件 + return NewDesign; + }); + + return { + currentComponent + }; + } +}); +</script> \ No newline at end of file diff --git a/src/main.ts b/src/main.ts new file mode 100644 index 0000000..615f3e3 --- /dev/null +++ b/src/main.ts @@ -0,0 +1,24 @@ +import './assets/base.css' + +import { createApp } from 'vue' +import App from './App.vue' +import router from './router' + +// 使用 element-plus +import ElementPlus from 'element-plus' +import 'element-plus/dist/index.css' + +import { createPinia } from "pinia"; + +// 引入echarts +import * as echarts from 'echarts'; + +const app = createApp(App) + +app.use(ElementPlus) +app.config.globalProperties.$echarts = echarts + +app.use(router) +app.use(createPinia()) + +app.mount('#app') diff --git a/src/router/index.ts b/src/router/index.ts new file mode 100644 index 0000000..80973d7 --- /dev/null +++ b/src/router/index.ts @@ -0,0 +1,63 @@ +import { createRouter, createWebHashHistory } from 'vue-router'; + +// const route = useRoute(); + + +const router = createRouter({ + history: createWebHashHistory(import.meta.env.BASE_URL), + routes: [ + { + path: '/', + name: 'root', + redirect: '/thenew', // 默认重定向到 /thenew + component: () => import('@/views/TheNewView.vue'), // 顶级路由组件 + children: [ + { + path: 'thenew', + name: 'thenew', + // component: () => import('@/views/HomeView.vue'), // HomeView 是 TheNewView 的子组件 + redirect: '/thenew/nodata', // 默认重定向到 /thenew/hour-line + children: [ + { + path: 'hour-line', + name: 'hour-line', + component: () => import('@/end/NewDesign.vue') // 嵌套子路由 + }, + { + path: 'hour-line2', + name: 'hour-line2', + component: () => import('@/endnew/NewStyleDesign.vue') // 嵌套子路由 + }, + { + path: 'day-line', + name: 'day-line', + component: () => import('@/end/NodataView.vue') // 嵌套子路由 + }, + { + path: 'week-line', + name: 'week-line', + component: () => import('@/end/NodataView.vue') // 嵌套子路由 + }, + { + path: 'month-line', + name: 'month-line', + component: () => import('@/end/NodataView.vue') // 嵌套子路由 + }, + { + path: 'year-line', + name: 'year-line', + component: () => import('@/end/NodataView.vue') // 嵌套子路由 + }, + { + path: 'nodata', + name: 'nodata', + component: () => import('@/end/NodataView.vue') // 嵌套子路由 + } + ] + } + ] + } + ] +}); + +export default router; \ No newline at end of file diff --git a/src/shims-vue.d.ts b/src/shims-vue.d.ts new file mode 100644 index 0000000..b0d039e --- /dev/null +++ b/src/shims-vue.d.ts @@ -0,0 +1,5 @@ +declare module '*.vue' { + import { DefineComponent } from 'vue'; + const component: DefineComponent<{}, {}, any>; + export default component; +} \ No newline at end of file diff --git a/src/store/index.ts b/src/store/index.ts new file mode 100644 index 0000000..757f71b --- /dev/null +++ b/src/store/index.ts @@ -0,0 +1,5 @@ +import { createPinia } from "pinia"; + +const pinia = createPinia() + +export default pinia diff --git a/src/store/usestylestore.ts b/src/store/usestylestore.ts new file mode 100644 index 0000000..e69de29 diff --git a/src/store/usethemestore.ts b/src/store/usethemestore.ts new file mode 100644 index 0000000..245000e --- /dev/null +++ b/src/store/usethemestore.ts @@ -0,0 +1,30 @@ +import { defineStore } from 'pinia' + +//数组处理 + + + +const useTheme = defineStore("Theme", { + state: () => ({ + theme: false, + fontcolor:'#fff', + style:'vertical' + }), + actions: { + toggleFontcolor(){ + if(this.theme){ + this.fontcolor = '#000' + }else{ + this.fontcolor = '#fff' + } + }, + toggleDarkTheme(){ + this.theme = false + }, + optionConfigData () { + + } + } +}) + +export default useTheme \ No newline at end of file diff --git a/src/uilts/vscode.ts b/src/uilts/vscode.ts new file mode 100644 index 0000000..a6e7098 --- /dev/null +++ b/src/uilts/vscode.ts @@ -0,0 +1,2 @@ +// @ts-ignore +// export const vscode= window.acquireVsCodeApi(); \ No newline at end of file diff --git a/src/utils/echarts.js b/src/utils/echarts.js new file mode 100644 index 0000000..ffc3fda --- /dev/null +++ b/src/utils/echarts.js @@ -0,0 +1,37 @@ +//这个必须要引入的 +import * as echarts from "echarts/core"; + +/** 引入柱状图and折线图图表,图表后缀都为 Chart*/ +import { BarChart, LineChart } from "echarts/charts"; + +// 引入提示框,标题,直角坐标系,数据集,内置数据转换器组件,组件后缀都为 Component +import { + TitleComponent, + TooltipComponent, + GridComponent, + DatasetComponent, + TransformComponent, +} from "echarts/components"; + +// 标签自动布局,全局过渡动画等特性 +import { LabelLayout, UniversalTransition } from "echarts/features"; + +// 引入 Canvas 渲染器,注意引入 CanvasRenderer 或者 SVGRenderer 是必须的一步 +import { CanvasRenderer } from "echarts/renderers"; + +// 注册必须的组件 +echarts.use([ + TitleComponent, + TooltipComponent, + GridComponent, + DatasetComponent, + TransformComponent, + BarChart, + LabelLayout, + UniversalTransition, + CanvasRenderer, + LineChart, +]); + +// 导出 +export default echarts; \ No newline at end of file diff --git a/src/utils/http.js b/src/utils/http.js new file mode 100644 index 0000000..2e51bf2 --- /dev/null +++ b/src/utils/http.js @@ -0,0 +1,45 @@ +import axios from 'axios' +const request = axios.create({ + method :"GET", + timeout:2000, +}) +// 请求拦截器 +request.interceptors.request.use(config => { + console.log("请求拦截成功") + // 例如给后端传递token,config是配置参数 + //如有需要:注意使用token的时候需要引入cookie方法或者用本地localStorage等方法,推荐js-cookie + //const token = getCookie('名称');//这里取token之前,你肯定需要先拿到token,存一下 + //if(token){ + //config.params = {'token':token} //如果要求携带在参数中 + //config.headers.token= token; //如果要求携带在请求头中 + return config +}, + error => { + console.log('请求拦截失败') + return Promise.reject(error) + } +) +// 响应拦截器 +request.interceptors.response.use(res => { + console.log("响应拦截成功") + if (res.status != 200) { + return + } else { + return res + } +}, + error => { + console.log("响应拦截失败") + return Promise.reject(error) + } +) +export default (url, method = "GET", params = {}) => { + return request({ + url, + method, + params + }) +} +// export default request + + diff --git a/src/utils/request.js b/src/utils/request.js new file mode 100644 index 0000000..3972db9 --- /dev/null +++ b/src/utils/request.js @@ -0,0 +1,57 @@ +// 进行axios的二次封装 +import axios from "axios"; +// 第一步:利用axios对象的create方法,去创建axios实例(其他的配置:基础路径,超时的时间) +let request=axios.create({ + // 基础路径 + baseURL:import.meta.env.VITE_APP_BASE_API,//基础路径上会携带/api + timeout:5000//超时的时间的设置 +}); +// 第二步:request实例添加请求与响应拦截器 +request.interceptors.request.use((config)=>{ + // config配置对象,headers属性请求头,经常给服务器端携带公共参数 + // 返回配置对象 + return config +}) +// 第三步:响应拦截器 +request.interceptors.response.use((response)=>{ + // 成功回调 + // 简化数据 + console.log(response); + + if(response.status==200){ + return response.data.message + } + + +},(error)=>{ + + // 失败回调:处理http网络问题 + // 定义一个变量:存储网络错误信息 + console.log(error); + + let message='' + // http状态码 + let status=error.response.status + switch(status){ + case 401: + message='TOKEN过期' + break; + case 403: + message ='无权访问' + break; + case 404: + message ='请求地址错误' + break; + case 500: + message ='服务器出现问题' + break; + default: + message='网络出现问题' + break + } + + return Promise.reject(error) +}) + +// 对外暴露 +export default request diff --git a/src/utils/vscode.ts b/src/utils/vscode.ts new file mode 100644 index 0000000..a6e7098 --- /dev/null +++ b/src/utils/vscode.ts @@ -0,0 +1,2 @@ +// @ts-ignore +// export const vscode= window.acquireVsCodeApi(); \ No newline at end of file diff --git a/src/views/HomeView.vue b/src/views/HomeView.vue new file mode 100644 index 0000000..be5f4dd --- /dev/null +++ b/src/views/HomeView.vue @@ -0,0 +1,240 @@ +<script setup> +import { onMounted, ref, watch} from 'vue' // 主要 +import { RouterView, useRouter } from 'vue-router' +import { storeToRefs } from 'pinia' + +import usethemestore from '../store/usethemestore' +const themeStore = usethemestore() +const { theme, style } = storeToRefs(themeStore) + +const router = useRouter() +let routerViewKey = ref(0) // 用于强制重新渲染 RouterView 的 key + +const props = defineProps({ + message: { + type: String, + default: '', // 默认值为空 + }, +}); + +const lightFunc = () => { + theme.value = true + document.documentElement.style.setProperty('--my-common-bgc-2', '#fff'); + document.documentElement.style.setProperty('--my-light-br-1', '#e7ebf3'); + document.documentElement.style.setProperty('--my-common-bgc-1', '#1F1F1F'); + document.documentElement.style.setProperty('--my-common-fc-1', '#1F1F1F'); + +} +const darkFunc = () => { + theme.value = false + document.documentElement.style.setProperty('--my-common-bgc-2', '#1F1F1F'); + document.documentElement.style.setProperty('--my-light-br-1', '#ffffff'); + document.documentElement.style.setProperty('--my-common-bgc-1', '#fff'); + document.documentElement.style.setProperty('--my-common-fc-1', '#fff'); +} + +const verticalFunc = () => { + style.value = 'vertical' + router.push({ + path: `/thenew/hour-line`, + params: { type: 'vertical' }, + }) + // routerViewKey.value = routerViewKey.value + 1 + +} +const gridFunc = () => { + style.value = 'grid' + router.push({ + path: `/thenew/hour-line2`, + params: { type: 'grid' }, + }) + // routerViewKey.value = routerViewKey.value + 1 + +} + +onMounted(() => { + watch(() => props.message, (news,old) => { + routerViewKey.value = routerViewKey.value + 1 + router.push(`/thenew/hour-line`) + activeIndex.value = 0 + }) +}) + +const headerData = ref([ + '日K', + '周K', + '月K', + '季K', + '年K', + // '1分', + // '3分', + // '5分', + // '15分', + // '30分', + // '1小时', + // '2小时', + // '3小时', + // '4小时', +]) +// 模拟路由数据 +let routerList = [ + 'hour-line', + 'day-line', + 'week-line', + 'month-line', + 'year-line', +] +// 定义一个响应式变量来存储当前激活的项的索引 +const activeIndex = ref(0) +// 定义一个处理点击事件的函数 +function handleClick(index) { + // 更新当前激活的项的索引 + activeIndex.value = index + // 跳转路由 + router.push(`/thenew/${routerList[index]}`) +} +</script> + +<template> + <div class="content"> + <ul class="timelist"> + <li + class="item" + v-for="(item, index) in headerData" + :key="item" + :class="{ active: activeIndex === index }" + @click="handleClick(index)" + > + {{ item }} + </li> + <li class="item"> + <el-dropdown :hide-on-click="false"> + <span class="el-dropdown-link"> + <div v-if="theme"> + <svg t="1739345471358" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="7366" width="16" height="16"><path d="M85.333333 128h853.333334v768H85.333333V128z m85.333334 85.333333v597.333334h682.666666V384h-341.333333V213.333333H170.666667z" p-id="7367" fill="#2c2c2c"></path></svg> + </div> + <div v-else> + <svg t="1739345471358" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="7366" width="16" height="16"><path d="M85.333333 128h853.333334v768H85.333333V128z m85.333334 85.333333v597.333334h682.666666V384h-341.333333V213.333333H170.666667z" p-id="7367" fill="#ffffff"></path></svg> + </div> + <!-- <svg t="1737685184492" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="1032" width="16" height="16"><path d="M831.085714 896h-612.571428V437.028571l-118.857143-118.857142 201.142857-201.142858 10.057143 10.057143c113.371429 113.371429 298.057143 113.371429 412.342857 0l10.057143-10.057143L950.857143 334.628571l-118.857143 118.857143V896z m-585.142857-27.428571h557.714286V441.6l106.971428-106.971429L732.342857 155.428571C610.742857 266.971429 423.314286 266.971429 301.714286 155.428571L138.057143 318.171429l106.971428 106.971428V868.571429z" fill="#2c2c2c" p-id="1033"></path></svg> --> + </span> + <template #dropdown> + <el-dropdown-menu> + <el-dropdown-item> + <div @click="verticalFunc"> + <el-tooltip + class="box-item" + effect="light" + content="垂直" + placement="left" + > + <svg t="1739337693471" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="6034" width="16" height="16"><path d="M85.333333 213.333333h853.333334v597.333334H85.333333V213.333333z m85.333334 85.333334v85.333333h682.666666V298.666667H170.666667z m682.666666 170.666666H170.666667v85.333334h682.666666v-85.333334z m0 170.666667H170.666667v85.333333h682.666666v-85.333333z" p-id="6035" fill="#2c2c2c"></path></svg> + </el-tooltip> + </div> + </el-dropdown-item> + <el-dropdown-item> + <div @click="gridFunc"> + <el-tooltip + class="box-item" + effect="light" + content="网格" + placement="left" + > + <svg t="1739339260343" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="7012" width="14" height="14"><path d="M85.333333 128h853.333334v768H85.333333V128z m85.333334 170.666667v213.333333h298.666666V298.666667H170.666667z m384 0v213.333333h298.666666V298.666667h-298.666666z m298.666666 298.666666h-298.666666v213.333334h298.666666v-213.333334z m-384 213.333334v-213.333334H170.666667v213.333334h298.666666z" p-id="7013" fill="#2c2c2c"></path></svg> + </el-tooltip> + </div> + </el-dropdown-item> + </el-dropdown-menu> + </template> + </el-dropdown> + </li> + <li class="item"> + <el-dropdown :hide-on-click="false"> + <span class="el-dropdown-link"> + <div v-if="theme"> + <svg t="1737685184492" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="1032" width="16" height="16"><path d="M831.085714 896h-612.571428V437.028571l-118.857143-118.857142 201.142857-201.142858 10.057143 10.057143c113.371429 113.371429 298.057143 113.371429 412.342857 0l10.057143-10.057143L950.857143 334.628571l-118.857143 118.857143V896z m-585.142857-27.428571h557.714286V441.6l106.971428-106.971429L732.342857 155.428571C610.742857 266.971429 423.314286 266.971429 301.714286 155.428571L138.057143 318.171429l106.971428 106.971428V868.571429z" fill="#2c2c2c" p-id="1033"></path></svg> + </div> + <div v-else> + <svg t="1737685184492" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="1032" width="16" height="16"><path d="M831.085714 896h-612.571428V437.028571l-118.857143-118.857142 201.142857-201.142858 10.057143 10.057143c113.371429 113.371429 298.057143 113.371429 412.342857 0l10.057143-10.057143L950.857143 334.628571l-118.857143 118.857143V896z m-585.142857-27.428571h557.714286V441.6l106.971428-106.971429L732.342857 155.428571C610.742857 266.971429 423.314286 266.971429 301.714286 155.428571L138.057143 318.171429l106.971428 106.971428V868.571429z" fill="#ffffff" p-id="1033"></path></svg> + </div> + <!-- <svg t="1737685184492" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="1032" width="16" height="16"><path d="M831.085714 896h-612.571428V437.028571l-118.857143-118.857142 201.142857-201.142858 10.057143 10.057143c113.371429 113.371429 298.057143 113.371429 412.342857 0l10.057143-10.057143L950.857143 334.628571l-118.857143 118.857143V896z m-585.142857-27.428571h557.714286V441.6l106.971428-106.971429L732.342857 155.428571C610.742857 266.971429 423.314286 266.971429 301.714286 155.428571L138.057143 318.171429l106.971428 106.971428V868.571429z" fill="#2c2c2c" p-id="1033"></path></svg> --> + </span> + <template #dropdown> + <el-dropdown-menu> + <el-dropdown-item> + <div @click="lightFunc"> + <el-tooltip + class="box-item" + effect="light" + content="Light" + placement="left" + > + <svg t="1737685432082" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="3218" width="16" height="16"><path d="M504.832 144h24.08c6.608 0 11.952 4.48 11.952 9.984v80.208c0 5.504-5.344 9.984-11.952 9.984h-24.08c-6.608 0-11.968-4.48-11.968-9.984V153.984c0-5.52 5.36-9.984 11.968-9.984z m10.304 541.92c96.432 0 174.608-78.176 174.608-174.608 0-96.448-78.176-174.624-174.608-174.624S340.528 414.88 340.528 511.312c0 96.432 78.176 174.608 174.608 174.608z m0 48c-122.944 0-222.608-99.68-222.608-222.608 0-122.944 99.664-222.624 222.608-222.624s222.608 99.68 222.608 222.624c0 122.928-99.68 222.608-222.608 222.608z m-10.24-355.792a9.52 9.52 0 0 1 10.24 9.488v247.2a9.696 9.696 0 0 1-10.448 9.648 133.584 133.584 0 0 1 0.208-266.336z m263.184-135.056l17.024 17.024c4.672 4.672 5.28 11.632 1.376 15.536L729.6 332.512c-3.904 3.904-10.864 3.296-15.52-1.376l-17.04-17.024c-4.672-4.672-5.28-11.632-1.376-15.552l56.88-56.864c3.904-3.92 10.864-3.296 15.52 1.376z m110.528 261.76v24.08c0 6.608-4.48 11.952-9.984 11.952h-80.208c-5.504 0-9.984-5.344-9.984-11.952v-24.08c0-6.608 4.48-11.968 9.984-11.968h80.208c5.52 0 9.984 5.36 9.984 11.968z m-93.504 257.68l-17.024 17.024c-4.672 4.672-11.632 5.28-15.536 1.376l-56.88-56.864c-3.904-3.92-3.296-10.88 1.376-15.536l17.024-17.04c4.672-4.672 11.632-5.28 15.536-1.376l56.88 56.88c3.92 3.904 3.296 10.88-1.376 15.536z m-256.192 116.096h-24.08c-6.608 0-11.968-4.48-11.968-9.984v-80.208c0-5.504 5.36-9.984 11.968-9.984h24.08c6.608 0 11.952 4.48 11.952 9.984v80.208c0 5.52-5.344 9.984-11.952 9.984z m-268.528-100.448l-14.272-14.272a10.016 10.016 0 0 1 0-14.16l56.88-56.88a10.016 10.016 0 0 1 14.16 0l14.272 14.272a10.016 10.016 0 0 1 0 14.176l-56.864 56.864a10.016 10.016 0 0 1-14.176 0zM144 528.912v-24.08c0-6.608 4.48-11.968 9.984-11.968h80.208c5.504 0 9.984 5.36 9.984 11.968v24.08c0 6.608-4.48 11.952-9.984 11.952H153.984c-5.52 0-9.984-5.344-9.984-11.952z m104.64-268.8l17.024-17.04c4.672-4.672 11.632-5.28 15.536-1.376l56.88 56.864c3.904 3.92 3.296 10.88-1.376 15.552l-17.04 17.024c-4.672 4.672-11.616 5.28-15.52 1.376l-56.88-56.88c-3.92-3.904-3.296-10.88 1.36-15.52z" fill="#2c2c2c" p-id="3219"></path></svg> + </el-tooltip> + </div> + </el-dropdown-item> + <el-dropdown-item> + <div @click="darkFunc"> + <el-tooltip + class="box-item" + effect="light" + content="Dark" + placement="left" + > + <svg t="1737685471806" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="3524" width="16" height="16"><path d="M504.832 144h24.08c6.608 0 11.952 4.48 11.952 9.984v80.208c0 5.504-5.344 9.984-11.952 9.984h-24.08c-6.608 0-11.968-4.48-11.968-9.984V153.984c0-5.52 5.36-9.984 11.968-9.984z m263.248 99.072l17.024 17.024c4.672 4.672 5.28 11.632 1.376 15.536L729.6 332.512c-3.904 3.904-10.864 3.296-15.52-1.376l-17.04-17.024c-4.672-4.672-5.28-11.632-1.376-15.552l56.88-56.864c3.904-3.92 10.864-3.296 15.52 1.376z m110.528 261.76v24.08c0 6.608-4.48 11.952-9.984 11.952h-80.208c-5.504 0-9.984-5.344-9.984-11.952v-24.08c0-6.608 4.48-11.968 9.984-11.968h80.208c5.52 0 9.984 5.36 9.984 11.968z m-93.504 257.68l-17.024 17.024c-4.672 4.672-11.632 5.28-15.536 1.376l-56.88-56.864c-3.904-3.92-3.296-10.88 1.376-15.536l17.024-17.04c4.672-4.672 11.632-5.28 15.536-1.376l56.88 56.88c3.92 3.904 3.296 10.88-1.376 15.536z m-256.192 116.096h-24.08c-6.608 0-11.968-4.48-11.968-9.984v-80.208c0-5.504 5.36-9.984 11.968-9.984h24.08c6.608 0 11.952 4.48 11.952 9.984v80.208c0 5.52-5.344 9.984-11.952 9.984z m-268.528-100.448l-14.272-14.272a10.016 10.016 0 0 1 0-14.16l56.88-56.88a10.016 10.016 0 0 1 14.16 0l14.272 14.272a10.016 10.016 0 0 1 0 14.176l-56.864 56.864a10.016 10.016 0 0 1-14.176 0zM144 528.912v-24.08c0-6.608 4.48-11.968 9.984-11.968h80.208c5.504 0 9.984 5.36 9.984 11.968v24.08c0 6.608-4.48 11.952-9.984 11.952H153.984c-5.52 0-9.984-5.344-9.984-11.952z m104.64-268.8l17.024-17.04c4.672-4.672 11.632-5.28 15.536-1.376l56.88 56.864c3.904 3.92 3.296 10.88-1.376 15.552l-17.04 17.024c-4.672 4.672-11.616 5.28-15.52 1.376l-56.88-56.88c-3.92-3.904-3.296-10.88 1.36-15.52zM515.12 685.92c96.432 0 174.608-78.176 174.608-174.608 0-96.448-78.176-174.624-174.608-174.624S340.528 414.88 340.528 511.312c0 96.432 78.176 174.608 174.608 174.608z m0 48c-122.944 0-222.608-99.68-222.608-222.608 0-122.944 99.664-222.624 222.608-222.624s222.608 99.68 222.608 222.624c0 122.928-99.68 222.608-222.608 222.608zM478.288 427.52a82.8 82.8 0 0 0-1.68 16.64c0 43.936 34.32 79.552 76.64 79.552a74.624 74.624 0 0 0 48.544-17.984c4.544-3.872 14.72-2.4 15.392 3.184 0.592 4.848 0.896 9.792 0.896 14.8 0 64.224-50.144 116.272-112 116.272s-112-52.048-112-116.272c0-48.064 28.096-89.312 68.176-107.024 6.976-3.088 17.312 4.576 16.032 10.832z" fill="#2c2c2c" p-id="3525"></path></svg> + </el-tooltip> + </div> + </el-dropdown-item> + </el-dropdown-menu> + </template> + </el-dropdown> + </li> + </ul> + <div class="view"> + <RouterView :key="routerViewKey"></RouterView> + </div> + </div> +</template> + +<style scoped> +.content { + /* width: 100vw; */ + height: 100vh; + display: flex; + flex-direction: column; + box-sizing: border-box; +} +.timelist { + /* background-color: white; */ + background-color: var(--my-common-bgc-2) !important; + /* color: #414040; */ + color: var(--my-common-fc-1); + font-size: 13px; + display: flex; + list-style: none; + border-bottom: 1px solid rgb(175, 173, 173); + box-sizing: border-box; + margin: 0; + padding: 2px 0; +} + +.timelist > li { + padding: 0 8px; + cursor: pointer; +} +.timelist > li:nth-child(6){ + margin-left: auto; + /* margin-right: 10px; */ +} + +.active { + color: #2d98b9; +} + +.view { + height: calc(100vh - 27px); +} +::-webkit-scrollbar { + width: 0; +} +</style> diff --git a/src/views/TheNewView.vue b/src/views/TheNewView.vue new file mode 100644 index 0000000..8a96f70 --- /dev/null +++ b/src/views/TheNewView.vue @@ -0,0 +1,1237 @@ +<script setup lang="ts"> +import { nextTick, ref, computed } from 'vue' +import { Edit, Plus, Delete, View, Hide,Operation } from '@element-plus/icons-vue' + +import { ElMessageBox, ElTable, ElMessage, ElLoading } from 'element-plus' +import type { CollapseModelValue } from 'element-plus' +import axios from 'axios' +// import { vscode } from './uilts/vscode' +import { RouterView } from 'vue-router' + +import HomeView from './HomeView.vue' +const message = ref(''); // 用于存储要发送的消息 + +const klineIframe = ref<HTMLIFrameElement | null>(null); // 引用 iframe 元素 + +// --------------------后台数据-------------- +axios({ + url: 'http://127.0.0.1:8012/akshare/userstrategy', + method: 'get', +}) + .then(async (res) => { + + const loading = ElLoading.service({ + lock: true, + text: 'Loading', + background: 'rgba(255, 255, 255, 0.7)', + }) + + + let userstockinfo = res.data + let promises = [] + + for (let i = 0; i < userstockinfo.length; i++) { + const element = userstockinfo[i] + let postinfo = { + pageNo: element.strategy_request.pageNo, + pageSize: element.strategy_request.pageSize, + year: element.strategy_request.year, + indexType: element.strategy_request.indexType, + thsIndexCode: element.strategy_request.thsIndexCode, + } + + // 创建一个Promise并将其添加到promises数组中 + promises.push( + axios + .post( + 'https://wance.cqxqg.tech/api/v1/strategy/getStockPageList', + postinfo, + { + headers: { + 'Content-Type': 'application/json', + }, + } + ) + .then((res) => { + console.log(res.data.data.list) + let nowdata = res.data.data.list + + let opt = [] + for (let j = 0; j < nowdata.length; j++) { + let flag = Number(nowdata[j].pctChg) > 0 ? true : false + let prc2 = parseFloat( + (Number(nowdata[j].pctChg) / 100).toFixed(2) + ) + opt.push({ + code: nowdata[j].stockCode, + name: nowdata[j].stockName, + market: nowdata[j].industryName, + newprice: Number(nowdata[j].psPercentage), + amplitudetype: flag, + amplitude: prc2, + type: element.strategy_request.indexType + }) + } + + myitems.value.push({ + id: '100096', + label: element.strategy_request.strategy_name, + value: element.strategy_request.strategy_name, + state: true, + info: opt, + inputClass: 'fixed', + fixchange: false, + }) + + // 存在自己的数据库表中 + let newpostparam = { + id: 100096, + strategy_name: element.strategy_request.strategy_name, + message: myitems.value, + info: opt, + } + // console.log(newpostparam) + + return axios.post( + 'http://127.0.0.1:8012/akshare/newuserstrategy', + newpostparam + ) + }) + ) + } + + // 等待所有Promise完成 + await Promise.all(promises) + + // 所有异步操作完成后,执行最后的axios.get请求 + axios.get('http://127.0.0.1:8012/akshare/newget').then((res) => { + console.log(res.data) + if (res.data.code == 200) { + loading.close() + ElMessage.success('数据获取成功') + items.value = res.data.data + addstocklog.value = res.data.data + } + + + }) + }) + .catch((err) => { + console.log(err) + }) + +const activeNames = ref(['0']) +const handleChange = (val: string[]) => { + console.log(val) +} + +const showChangeVisible = ref(true) + +const handleTitleClick = async () => { + showChangeVisible.value = !showChangeVisible.value +} + +const dialogVisible = ref(false) +const handleClose = (done: () => void) => { + ElMessageBox.confirm('当前操作会关闭对话框?', { + confirmButtonText: '确认', + cancelButtonText: '取消', + }) + .then(() => { + done() + }) + .catch(() => { + // catch error + }) +} + +// -------------------股票信息------------------------------- + + +interface StockType { + id?: string + label: string + value: string + state: boolean + info: Equity[] + message?: { info: Equity[] }[] +} + +let cacheinfo = ref<Equity[]>([]) + +let stocktypes = ref<StockType[]>([ + { + id: '1', + label: '港股', + value: '港股', + state: true, + info: [], + }, + { + id: '2', + label: '美股', + value: '美股', + state: true, + info: [], + }, + { + id: '3', + label: '沪深', + value: '沪深', + state: true, + info: [], + } +]) +axios({ + url: 'http://127.0.0.1:8012/akshare/ganggudata', + method: 'get', +}).then((res) => { + stocktypes.value[0].info = res.data + cacheinfo.value.push(res.data) + }) +axios({ + url: 'http://127.0.0.1:8012/akshare/meigudata', + method: 'get', + }).then((res) => { + stocktypes.value[1].info = res.data + cacheinfo.value.push(res.data) +}) +axios({ + url: 'http://127.0.0.1:8012/akshare/hushendata', + method: 'get', + }).then((res) => { + stocktypes.value[2].info = res.data + cacheinfo.value.push(res.data) +}) +// --------------------切换是否可见-------------------------- +const changestate = (item: any) => { + item.state = !item.state + // console.log(item.state) +} + +let asideshow = computed(() => { + // console.log(stocktypes.value) + + return stocktypes.value.filter((item) => item.state) +}) + +// ---------------------新增股票测试数据--------------------------- +interface Equity { + code: string + name: string + market: string + newprice: number + amplitudetype: boolean + amplitude: number + type?: string +} + +// ---------------------往info数组里面加股票数据------------------- +const inputhandle = ref('') +const filterTableData = computed(() =>{ + let newarr = cacheinfo.value.flat(); // 使用 flat 方法将多维数组展平 + return newarr.filter( + (data) => + !inputhandle.value || + data.code.toLowerCase().includes(inputhandle.value.toLowerCase()) || + data.name.includes(inputhandle.value) + ); +}) +// 添加新股票完成 +const handleEdit = (index: number, row: Equity) => { + console.log(index, row) + + stocklog.value?.info.push(row) + + // 添加后移除,也可以不移除 + // tableData2.value = tableData2.value.filter((data) => data.code !== row.code) + + let mes = myitems.value[index] || '' + // 存在自己的数据库表中 + let newpostparam = { + id: 100096, + strategy_name: chosename.value, + message: [mes], + info: showdata.value, + } + + axios.post('http://127.0.0.1:8012/akshare/newupdata', newpostparam) +} + +// ---------------------------------新增分组测试数据---------------------------------- +interface NewAddGroup extends StockType { + inputClass: string + fixchange: boolean + strategy_name?: string +} +const items = ref<NewAddGroup[]>([]) +const myitems = ref<NewAddGroup[]>([]) +// items.value = [ +// { +// label: '川股', +// value: '川股', +// state: true, +// info: [], +// inputClass: 'fixed', +// fixchange: false, +// }, +// ] + +// ---------------------------------自定义分组修改------------------------------------- +const inputdemo = ref<(HTMLInputElement | null)[]>([]) +// 保存之前的的值 +let rename = ref('') +const changeEdit = async (item: any, index: number) => { + item.fixchange = true + rename.value = item.strategy_name + await nextTick() + // 如果切换到编辑状态,聚焦输入框 + if (!item.fixchange) { + nextTick(() => { + const inputElement = inputdemo.value[index] + if (inputElement) { + inputElement.focus() + } + }) + } +} +const changeDelete = (item: any, index: number) => { + ElMessageBox.confirm('当前操作会删除分组,是否继续?', { + confirmButtonText: '确认', + cancelButtonText: '取消', + }) + .then(() => { + // 从 items 数组中删除对应项 + items.value.splice(index, 1) + console.log(item.strategy_name) + + let newpostparam = { + strategy_name: item.strategy_name, + } + + // 删除分组完成 + axios.post('http://127.0.0.1:8012/akshare/newdel', newpostparam) + }) + .catch(() => { + console.log('这是取消操作按钮信息') + }) +} + +const handleFocus = (item: any, index: number) => { + // 切换当前元素的 fixchange 状态 + // item.fixchange = true; +} +const handleBlur = (item: any, index: number) => { + console.log(item); + + item.fixchange = false + if (rename.value != item.strategy_name) { + axios({ + method: 'get', + url: 'http://127.0.0.1:8012/akshare/newmodify', + params: { + strategy_name: rename.value, + new_strategy_name: inputdemo.value[index]?.value, + }, + }).then((res) => { + // console.log(res.data) + }) + } +} + +// ---------------------------------添加分组------------------------------ +let addialog = ref(false) +let addinput = ref('') +const addialogT = async() => { + let regex = /^[^\s]{1,10}$/ + if (!regex.test(addinput.value)) { + ElMessageBox.alert('分组名称不能为空或超过10个字符', '提示', { + confirmButtonText: '确定', + }) + return + } + + // 添加到数据库中 + let newpostparam = { + id: 100096, + strategy_name: addinput.value, + message: [], + info: [], + } + let promises = [] + promises.push(axios.post('http://127.0.0.1:8012/akshare/newadd', newpostparam).then(res => { + console.log(res.data); + if (res.data.code === 200){ + ElMessage.success('新建分组成功') + items.value.push({ + label: addinput.value, + value: addinput.value, + inputClass: 'fixed', + fixchange: false, + state: true, + info: [], + }) + addinput.value = '' + addialog.value = false + } + if (res.data.code === 204){ + ElMessage.error('该分组已存在') + } + + })) + + // 等待所有Promise完成 + await Promise.all(promises) + + + + // 所有异步操作完成后,执行最后的axios.get请求 + axios.get('http://127.0.0.1:8012/akshare/newget').then((res) => { + // console.log(res.data) + if (res.data.code == 200) { + ElMessage.success('数据获取成功') + items.value = res.data.data + addstocklog.value = res.data.data + } + + + }) +} + +// -------------------------------------------------------------------- + +// --------------------------------操作列表的逻辑----------------------------------- + +const delvisible = ref(false) +const clevisible = ref(false) +// 被选中的 +let alreadySelected = ref<Equity[]>([]) +// 选中checkbox +const handleselect = (val: Equity[]) => { + // 这里的val已经是一个记录被选中元素的数组,直接进行赋值即可 + alreadySelected.value = val +} +// 删除已选元素的函数逻辑 +const removeSelected = () => { + // 清空已选中元素的选中状态 + alreadySelected.value.forEach((selectedItem) => { + const index = stocklog.value?.info.findIndex( + (item) => + item.code === selectedItem.code && + item.name === selectedItem.name && + item.market === selectedItem.market + ) + if (index !== undefined && index !== -1) { + stocklog.value?.info.splice(index, 1) + } + }) + // 清空已选中元素数组 + alreadySelected.value = [] +} + +const delmyselect = () => { + removeSelected() + + delvisible.value = false + + // 存在自己的数据库表中 + let newpostparam = { + id: 100096, + strategy_name: chosename.value, + message: [ + { + id: '100096', + label: chosename.value, + value: chosename.value, + state: true, + info: showdata.value, + inputClass: 'fixed', + fixchange: false, + }, + ], + info: showdata.value, + } + axios.post('http://127.0.0.1:8012/akshare/newupdata', newpostparam) +} + +// 清空所有元素 +const clearall = () => { + if (stocklog.value) { + stocklog.value.info = [] + + let newpostparam = { + id: 100096, + strategy_name: chosename.value, + message: [], + info: [], + } + axios.post('http://127.0.0.1:8012/akshare/newupdata', newpostparam) + } else { + console.warn('stocktypes 数组为空') + } + clevisible.value = false +} +// 当用户手动勾选全选 Checkbox 时触发的事件 +const handleSelectionChange = (val: Equity[]) => { + // 这里的val已经是一个记录被选中元素的数组,直接精选复制即可 + alreadySelected.value = val +} +// ---------------------------------------------------------------------------------- + +// --------------------------------自选分组切换的逻辑----------------------------------- + +let stocklog = ref<StockType | null>(null) +let addstocklog = ref<any>(null) + +// 将 stocktypes 的第一项数据赋值给 stocklog +if (stocktypes.value.length > 0) { + stocklog.value = stocktypes.value[0] +} else { + console.warn('stocktypes 数组为空,无法赋值给 stocklog') +} + +// 判断选择的第几项,这里记录一下点击的是那一只分组 +let chosename = ref<string>('港股') + +const nowchose = (item: any) => { + stocklog.value = item + addstocklog.value = item + + chosename.value = item.strategy_name +} +// 利用计算属性将股票数据展示出来 +let showdata = computed(() => { + return stocklog.value?.info || [] +}) + +// --------------------------------------------------------------------------------- + +// -----------------------------侧边栏股票选择--------------------------------------- +let kindofstock = ref() +const clickTypeState = (val: CollapseModelValue) => { + kindofstock.value = val +} +const chioseStock = (item: any) => { + + // vscode.postMessage({ + // command: 'showkline', + // text: item.code, + // }) + + // window.postMessage(item.code,'*'); // 发送消息 + // 如果需要与 iframe 中的内容交互,可以通过 postMessage 发送消息 + // if (klineIframe.value && klineIframe.value.contentWindow) { + // klineIframe.value.contentWindow.postMessage( + // { type: 'SHOW_KLINE', data: item.code }, + // '*' // 目标 origin,设置为 '*' 表示不限制 + // ); + // } + + message.value = item.code; // 设置消息内容 + + if(kindofstock.value == '港股'){ + axios({ + url: 'http://127.0.0.1:8012/akshare/ganggudataK', + method: 'get', + params: { + symbol: item.code, + start_date: '2023-01-01', + end_date: getDate() + }, + }).then((res) => { + console.log('数据传输成功') + }) + } + else if(kindofstock.value == '美股'){ + axios({ + url: 'http://127.0.0.1:8012/akshare/meigudataK', + method: 'get', + params: { + symbol: item.code, + start_date: '2023-01-01', + end_date: getDate() + }, + }).then((res) => { + console.log('数据传输成功') + }) + } + else if(kindofstock.value == '沪深'){ + axios({ + url: 'http://127.0.0.1:8012/akshare/hushendataK', + method: 'get', + params: { + symbol: item.code, + start_date: '2023-01-01', + end_date: getDate() + }, + }).then((res) => { + console.log('数据传输成功') + }) + } + +} +// --------------------------------------------- +// -------------------------------更新日期----------------------------------------- +const getDate = () => { + const date = new Date(); + const year = date.getFullYear(); + const month = String(date.getMonth() + 1).padStart(2, '0'); // 补零 + const day = String(date.getDate()).padStart(2, '0'); // 补零 + let formattedDate = `${year}-${month}-${day}`; + return formattedDate +} + +const sendmessage = (content: any) => { + axios({ + url: 'http://127.0.0.1:8012/akshare/stock', + method: 'get', + params: { + symbol: 'sz' + content.code, + start_date: '2023-01-01', + end_date: getDate() + }, + }).then((res) => { + console.log('数据传输成功') + }).catch(error => { + console.error(error); + }); +} + +const showkline = (content: any) => { + + + // vscode.postMessage({ + // command: 'showkline', + // text: content.code, + // }) + // window.postMessage(content.code,'*'); // 发送消息 + + // 如果需要与 iframe 中的内容交互,可以通过 postMessage 发送消息 + // if (klineIframe.value && klineIframe.value.contentWindow) { + // klineIframe.value.contentWindow.postMessage( + // { type: 'SHOW_KLINE', data: content.code }, + // '*' // 目标 origin,设置为 '*' 表示不限制 + // ); + // } + + message.value = content.code; // 设置消息内容 + + console.log(content); + if(content.type == "hs300"){ + sendmessage(content) + } + if(content.type == "zz500"){ + sendmessage(content) + } + if(content.type == "sse"){ + sendmessage(content) + } + if(content.type == "szse"){ + sendmessage(content) + } + if(content.type == "zz1000"){ + sendmessage(content) + } + if(content.type == "gz2000"){ + sendmessage(content) + } + if(content.type == "other"){ + sendmessage(content) + } + if(content.type == "ganggu"){ + axios({ + url: 'http://127.0.0.1:8012/akshare/ganggudataK', + method: 'get', + params: { + symbol: content.code, + start_date: '2023-01-01', + end_date: getDate() + }, + }).then((res) => { + console.log('数据传输成功') + }) + } + if(content.type == "meigu"){ + axios({ + url: 'http://127.0.0.1:8012/akshare/meigudataK', + method: 'get', + params: { + symbol: content.code, + start_date: '2023-01-01', + end_date: getDate() + }, + }).then((res) => { + console.log('数据传输成功') + }) + } + if(content.type == "hushen"){ + axios({ + url: 'http://127.0.0.1:8012/akshare/hushendataK', + method: 'get', + params: { + symbol: content.code, + start_date: '2023-01-01', + end_date: getDate() + }, + }).then((res) => { + console.log('数据传输成功') + }) + } + + + +} +</script> + +<template> + <div class="container"> + <div class="box"> + <div class="head"> + <div class="item">名称</div> + <div class="item">最新价</div> + <div class="item">涨跌幅</div> + </div> + <div class="all"> + <div class="showchange" @click="handleTitleClick">全部</div> + <div plain @click="dialogVisible = true"> + <!-- <el-icon><Plus /></el-icon> --> + <el-icon><Operation /></el-icon> + </div> + + <el-dialog + v-model="dialogVisible" + :modal="false" + :mask="false" + title="分组管理" + :before-close="handleClose" + width="1000" + > + <hr /> + <div class="onedialog"> + <div class="oneconleft"> + <div class="onecontitle">自选分组</div> + <div class="onestocks"> + <div class="one-item-name">全部</div> + <div class="one-items"> + <div + class="one-item" + v-for="item in stocktypes" + :key="item.value" + > + <div class="stock1" @click="nowchose(item)"> + {{ item.value }} + </div> + <div v-if="item.state" @click="changestate(item)"> + <el-icon><View /></el-icon> + </div> + <div v-if="!item.state" @click="changestate(item)"> + <el-icon><Hide /></el-icon> + </div> + </div> + + <div + v-for="(item, index) in items" + :key="index" + class="one-item" + > + <div class="stock2"> + <input + :class="{ + fixed: !item.fixchange, + isfixed: item.fixchange, + }" + type="text" + v-model="item.strategy_name" + @focus="handleFocus(item, index)" + @blur="handleBlur(item, index)" + @click="nowchose(item)" + :ref="(el) => (inputdemo[index] = el as HTMLInputElement)" + :readonly="!item.fixchange" + /> + </div> + <div> + <el-icon><Edit @click="changeEdit(item, index)" /></el-icon> + <el-icon + ><Delete @click="changeDelete(item, index)" + /></el-icon> + </div> + </div> + </div> + </div> + + <div class="oneadd"> + <el-button type="primary" size="small" @click="addialog = true"> + <el-icon><Plus /></el-icon>添加分组 + </el-button> + + <el-dialog v-model="addialog" title="添加分组" width="300"> + <div class="addtext"> + <div>请输入自选股分组名称</div> + <el-input + v-model="addinput" + placeholder="最多10个字" + ></el-input> + </div> + <template #footer> + <div class="dialog-footer"> + <el-button type="primary" @click="addialogT()" + >确认</el-button + > + <el-button @click="addialog = false">取消</el-button> + </div> + </template> + </el-dialog> + </div> + </div> + + <div class="oneconcenter"> + <div class="onecontitle">股票列表详情</div> + <div class="onetable"> + <el-table + border + :data="showdata" + style="width: 100%; font-size: 12px;height: 350px;" + @select-all="handleSelectionChange" + @select="handleselect" + > + <el-table-column type="selection" /> + <el-table-column property="code" label="代码" /> + <el-table-column property="name" label="名称" /> + <el-table-column property="type" label="市场" /> + </el-table> + </div> + </div> + + <div class="oneconright"> + <div class="onecontitle">加入股票</div> + <div class="add"> + <el-input + v-model="inputhandle" + size="small" + placeholder="代码/名称" + /> + <el-table + v-if="inputhandle" + :data="filterTableData" + style="width: 100%; height: 160px; font-size: 12px" + > + <el-table-column label="代码" prop="code" /> + <el-table-column label="名称" prop="name" /> + <el-table-column> + <template #header> 操作 </template> + <template #default="scope"> + <el-button + size="small" + @click="handleEdit(scope.$index, scope.row)" + > + 加入 + </el-button> + </template> + </el-table-column> + </el-table> + </div> + + <div class="listedit"> + <div>列表操作</div> + <div> + <el-popover :visible="delvisible" placement="top" :width="160"> + <p>是否删除已选中?</p> + <div style="text-align: right; margin: 0"> + <el-button size="small" text @click="delvisible = false" + >否</el-button + > + <el-button + size="small" + type="primary" + @click="delmyselect()" + >是</el-button + > + </div> + <template #reference> + <el-button + type="primary" + plain + size="small" + @click="delvisible = true" + >删除</el-button + > + </template> + </el-popover> + </div> + <div> + <el-popover :visible="clevisible" placement="top" :width="160"> + <p>是否全部清空?</p> + <div style="text-align: right; margin: 0"> + <el-button size="small" text @click="clevisible = false" + >否</el-button + > + <el-button size="small" type="primary" @click="clearall()" + >是</el-button + > + </div> + <template #reference> + <el-button + type="primary" + plain + size="small" + @click="clevisible = true" + >清空</el-button + > + </template> + </el-popover> + </div> + </div> + </div> + </div> + + <template #footer> + <div class="dialog-footer"> + <!-- <el-button @click="dialogVisible = false">取消</el-button> --> + <el-button type="primary" @click="dialogVisible = false" + >关闭</el-button + > + </div> + </template> + </el-dialog> + </div> + + <div class="demo-collapse" :style="{ display: showChangeVisible ? 'block' : 'none' }"> + <el-collapse v-model="activeNames" accordion @change="clickTypeState"> + + <el-collapse-item + :title="item.value" + :name="item.label" + v-for="(item, index) in asideshow" + :key="item.label" + + > + <div class="stock" v-for="content in item.info" :key="content.name" @click="chioseStock(content)"> + <div class="stockname" :title="content.name">{{ content.name }}</div> + <div :class="{upcolor: content.amplitudetype,downcolor: !content.amplitudetype}" :title="kindofstock"> + {{ content.newprice }} + </div> + <div :class="{stockchangeup: content.amplitudetype,stockchangedown: !content.amplitudetype}"> + {{ + content.amplitudetype ? '+' + content.amplitude : content.amplitude + }} + </div> + </div> + </el-collapse-item> + + + <el-collapse-item + :title="item.strategy_name" + :name="item.strategy_name" + v-for="(item, index) in items" + :key="item.label" + > + <div + class="stock" + v-for="content in item.info" + :key="content.name" + @click="showkline(content)" + > + <div class="stockname" :title="content.name"> + {{ content.name }} + </div> + <div + :class="{ + upcolor: content.amplitudetype, + downcolor: !content.amplitudetype, + }" + > + {{ content.newprice }} + </div> + <div + :class="{ + stockchangeup: content.amplitudetype, + stockchangedown: !content.amplitudetype, + }" + > + {{ + content.amplitudetype + ? '+' + content.amplitude + : content.amplitude + }} + </div> + </div> + </el-collapse-item> + + </el-collapse> + </div> + </div> + <div class="shape"> + <HomeView :message="message"/> + </div> + </div> + +</template> + +<style scoped> +.container{ + width: 100vw; + height: 100vh; + display: flex; +} +.box { + width: 300px; + /* flex: 3; */ + height: 100vh; + overflow-y: auto; + overflow-x: hidden; + box-sizing: border-box; + background-color: var(--my-common-bgc-2); + position: relative; + border-right: 1px solid var(--my-light-br-1); + +} +.shape{ + flex: 1; + height: 100vh; +} +iframe{ + width: 100%; + height: 100%; +} +.head { + /* width: 300px; */ + background-color: var(--my-common-bgc-2); + color: var(--my-common-bgc-1); + display: flex; + justify-content: space-around; + align-items: center; + padding:2px 0 0 12px; + + position: sticky; + top: 0; + z-index: 999; +} +.item { + font-size: 13px; + width: 52px; + text-align: center; + cursor: pointer; +} +.all { + display: flex; + align-items: center; + font-size: 13px; + padding: 10px 12px; + box-sizing: border-box; + position: sticky; + top: 17px; + z-index: 99; + color: var(--my-common-bgc-1); + background-color: var(--my-common-bgc-2); +} +.showchange { + flex: 1; + cursor: pointer; +} + +.onedialog { + display: flex; + height: 376px; + padding: 10px; + overflow: auto; +} +.onecontitle { + font-size: 13px; + font-weight: 550; + position: sticky; + top: 0; + z-index: 999; + background-color: #fff; +} +.onestocks { + margin-top: 10px; + font-size: 12px; + background-color: #ececec; + border-radius: 5px; + cursor: pointer; +} +.oneadd { + display: flex; + justify-content: center; + padding: 10px 0; +} +.one-item-name { + padding: 5px 10px; + background-color: #e7ebf3; +} +.one-item { + padding: 5px 10px; + display: flex; + align-items: center; +} +.one-items{ + height: 277px; + overflow: auto; +} +.oneconleft { + flex: 2; + min-width: 158px; + box-sizing: border-box; + padding-right: 10px; + height: 376px; + overflow: auto; + position: relative; +} +.oneconcenter { + flex: 3; + max-width: 320px; + padding: 0 10px; + border-left: 2px solid #ececec; + box-sizing: border-box; + height: 376px; + overflow: hidden; + position: relative; +} +.onetable { + font-size: 12px; + /* border: 1px solid red; */ + margin-top: 10px; + box-sizing: border-box; +} +.oneconright { + flex: 2; + box-sizing: border-box; + padding-left: 10px; + position: relative; +} + +.add { + margin-top: 10px; + width: 100%; + max-width: 300px; + box-sizing: border-box; +} + +.addtext { + padding: 10px 20px; +} +.addtext > div { + margin-bottom: 20px; +} +.listedit { + font-size: 13px; + font-weight: 550; + margin-top: 10px; +} +.listedit > div { + margin-bottom: 10px; +} +.stock { + flex: 1; + display: flex; + justify-content: space-around; + align-items: center; + margin-bottom: 5px; + cursor: pointer; + +} +:deep(.el-collapse-item__header){ + background-color: var(--my-common-bgc-2) !important; + color: var(--my-common-bgc-1); +} + +.stock1 { + flex: 1; + display: flex; + align-items: center; + margin-bottom: 5px; + cursor: pointer; +} +.stock2 { + /* border: 1px solid red; */ + flex: 1; + display: flex; + justify-content: left; + align-items: center; + margin-bottom: 5px; + cursor: pointer; +} +.stockname { + width: 52px; + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; +} + +.upcolor { + color: rgb(204, 42, 42); +} +.stockchangeup { + color: rgb(204, 42, 42); + background-color: rgba(255, 0, 0, 0.12); + border-radius: 4px; + width: 50px; + text-align: center; + /* padding: 2px; */ +} +.downcolor { + color: rgb(80, 165, 72); +} +.stockchangedown { + color: rgb(80, 165, 72); + background-color: rgba(60, 255, 0, 0.12); + border-radius: 4px; + width: 50px; + text-align: center; + /* padding: 2px; */ +} +:deep(.el-collapse-item__content) { + padding-bottom: 0; + max-height: 250px; + overflow-y: auto; + background-color: var(--my-common-bgc-2) !important; + color: var(--my-common-fc-1); +} +:deep(.el-collapse-item__content)::-webkit-scrollbar { + width: 0; +} + + +/* :deep(.el-collapse-item__content)::-webkit-scrollbar { + width: 5px; +} + +:deep(.el-collapse-item__content)::-webkit-scrollbar-track { + background: #f1f1f1; + border-radius: 6px; +} + +:deep(.el-collapse-item__content)::-webkit-scrollbar-thumb { + background: rgba(204, 42, 42,.2); + border-radius: 6px; +} */ + + + + + + +:deep(.demo-collapse) { + padding-left: 12px; +} + +.fixed { + outline: none; + border: none; + background-color: transparent; + font-size: 12px; + color: rgb(88, 87, 87); + cursor: pointer; +} + +.isfixed { + border: none; + outline: 1px solid rgb(131, 200, 218); + font-size: 12px; +} +/* 设置滚动条的样式 */ +::-webkit-scrollbar { + width: 0; +} + +</style> diff --git a/tsconfig.app.json b/tsconfig.app.json new file mode 100644 index 0000000..913b8f2 --- /dev/null +++ b/tsconfig.app.json @@ -0,0 +1,12 @@ +{ + "extends": "@vue/tsconfig/tsconfig.dom.json", + "include": ["env.d.ts", "src/**/*", "src/**/*.vue"], + "exclude": ["src/**/__tests__/*"], + "compilerOptions": { + "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.app.tsbuildinfo", + + "paths": { + "@/*": ["./src/*"] + } + } +} diff --git a/tsconfig.json b/tsconfig.json new file mode 100644 index 0000000..66b5e57 --- /dev/null +++ b/tsconfig.json @@ -0,0 +1,11 @@ +{ + "files": [], + "references": [ + { + "path": "./tsconfig.node.json" + }, + { + "path": "./tsconfig.app.json" + } + ] +} diff --git a/tsconfig.node.json b/tsconfig.node.json new file mode 100644 index 0000000..4c399c2 --- /dev/null +++ b/tsconfig.node.json @@ -0,0 +1,18 @@ +{ + "extends": "@tsconfig/node22/tsconfig.json", + "include": [ + "vite.config.*", + "vitest.config.*", + "cypress.config.*", + "nightwatch.conf.*", + "playwright.config.*" + ], + "compilerOptions": { + "noEmit": true, + "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.node.tsbuildinfo", + + "module": "ESNext", + "moduleResolution": "Bundler", + "types": ["node"] + } +} diff --git a/vite.config.ts b/vite.config.ts new file mode 100644 index 0000000..3ef1bfe --- /dev/null +++ b/vite.config.ts @@ -0,0 +1,30 @@ +import { fileURLToPath, URL } from 'node:url' + +import { defineConfig } from 'vite' +import vue from '@vitejs/plugin-vue' +import vueDevTools from 'vite-plugin-vue-devtools' + +// https://vite.dev/config/ +export default defineConfig({ + base: './', + plugins: [ + vue(), + vueDevTools(), + ], + resolve: { + alias: { + '@': fileURLToPath(new URL('./src', import.meta.url)) + }, + }, + server: { + open: true, + proxy: { + "/api/v1": { + // target: "http://10.1.5.188:8011/", + target: "http://127.0.0.1:8012", + changeOrigin: true, + rewrite: path => path.replace(/^\/api\/v1/, ''), + }, + }, +}, +})