QYF-GitLab1
2025-02-28 7a07041e87f5fea69ad4d83868f095c6b612e710
初始化结构
2个文件已修改
41个文件已添加
6652 ■■■■■ 已修改文件
.gitignore 43 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
.vite/deps/_metadata.json 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
.vite/deps/package.json 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
.vscode/extensions.json 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
README.md 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
index.html 13 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
package-lock.json 2412 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
package.json 27 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
public/vite.svg 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/App.vue 45 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/assets/js/canvas2image.js 266 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/assets/js/config.js 31 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/assets/js/iframe.js 32 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/assets/js/middleGround/WebMiddleGroundApi.js 24 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/assets/js/middleGround/api/app.js 82 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/assets/js/middleGround/api/edu.js 319 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/assets/js/middleGround/api/file.js 94 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/assets/js/middleGround/api/identity.js 225 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/assets/js/middleGround/api/job.js 34 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/assets/js/middleGround/api/resource.js 223 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/assets/js/middleGround/api/store.js 903 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/assets/js/middleGround/api/ugc.js 117 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/assets/js/middleGround/tool.js 448 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/assets/js/toolClass.js 467 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/assets/js/userAction.js 135 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/assets/vue.svg 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/components/HelloWorld.vue 43 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/components/SearchBar.vue 29 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/components/TreeMenu.vue 127 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/layout/Header.vue 91 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/layout/main.vue 补丁 | 查看 | 原始文档 | blame | 历史
src/main.js 21 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/plugin/axios/index.ts 85 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/router/index.ts 43 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/style.css 117 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/styles/global.less 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/model/Kinematic.vue 14 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/model/Mechanism.vue 14 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/simulation/Config.vue 14 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/simulation/Result.vue 14 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/system/Permission.vue 14 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/system/User.vue 14 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
vite.config.js 31 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
.gitignore
@@ -1,23 +1,24 @@
# Object files
*.o
*.ko
*.obj
*.elf
# Logs
logs
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*
pnpm-debug.log*
lerna-debug.log*
# Libraries
*.lib
*.a
node_modules
dist
dist-ssr
*.local
# Shared objects (inc. Windows DLLs)
*.dll
*.so
*.so.*
*.dylib
# Executables
*.exe
*.out
*.app
*.i*86
*.x86_64
*.hex
# Editor directories and files
.vscode/*
!.vscode/extensions.json
.idea
.DS_Store
*.suo
*.ntvs*
*.njsproj
*.sln
*.sw?
.vite/deps/_metadata.json
New file
@@ -0,0 +1,8 @@
{
  "hash": "01764690",
  "configHash": "11970981",
  "lockfileHash": "e3b0c442",
  "browserHash": "61d1b31d",
  "optimized": {},
  "chunks": {}
}
.vite/deps/package.json
New file
@@ -0,0 +1,3 @@
{
  "type": "module"
}
.vscode/extensions.json
New file
@@ -0,0 +1,3 @@
{
  "recommendations": ["Vue.volar"]
}
README.md
@@ -1,4 +1,5 @@
## modelLibrary
# Vue 3 + Vite
模型库管理
This template should help get you started developing with Vue 3 in Vite. The template uses Vue 3 `<script setup>` SFCs, check out the [script setup docs](https://v3.vuejs.org/api/sfc-script-setup.html#sfc-script-setup) to learn more.
Learn more about IDE Support for Vue in the [Vue Docs Scaling up Guide](https://vuejs.org/guide/scaling-up/tooling.html#ide-support).
index.html
New file
@@ -0,0 +1,13 @@
<!doctype html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <link rel="icon" type="image/svg+xml" href="/vite.svg" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Vite</title>
  </head>
  <body>
    <div id="app"></div>
    <script type="module" src="/src/main.js"></script>
  </body>
</html>
package-lock.json
New file
@@ -0,0 +1,2412 @@
{
  "name": "my-vue-app",
  "version": "0.0.0",
  "lockfileVersion": 2,
  "requires": true,
  "packages": {
    "": {
      "name": "my-vue-app",
      "version": "0.0.0",
      "dependencies": {
        "@element-plus/icons-vue": "^2.3.1",
        "element-plus": "^2.5.6",
        "vue": "^3.4.21",
        "vue-router": "^4.3.0"
      },
      "devDependencies": {
        "@vitejs/plugin-vue": "^5.0.4",
        "less": "^4.2.2",
        "less-loader": "^12.2.0",
        "vite": "^5.1.6"
      }
    },
    "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==",
      "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==",
      "engines": {
        "node": ">=6.9.0"
      }
    },
    "node_modules/@babel/parser": {
      "version": "7.26.9",
      "resolved": "https://registry.npmmirror.com/@babel/parser/-/parser-7.26.9.tgz",
      "integrity": "sha512-81NWa1njQblgZbQHxWHpxxCzNsa3ZwvFqpUg7P+NNUU6f3UU2jBEg4OlF/J6rl8+PQGh1q6/zWScd001YwcA5A==",
      "dependencies": {
        "@babel/types": "^7.26.9"
      },
      "bin": {
        "parser": "bin/babel-parser.js"
      },
      "engines": {
        "node": ">=6.0.0"
      }
    },
    "node_modules/@babel/types": {
      "version": "7.26.9",
      "resolved": "https://registry.npmmirror.com/@babel/types/-/types-7.26.9.tgz",
      "integrity": "sha512-Y3IR1cRnOxOCDvMmNiym7XpXQ93iGDDPHx+Zj+NM+rg0fBaShfQLkg+hKPaZCEvg5N/LeCo4+Rj/i3FuJsIQaw==",
      "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==",
      "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==",
      "peerDependencies": {
        "vue": "^3.2.0"
      }
    },
    "node_modules/@esbuild/aix-ppc64": {
      "version": "0.21.5",
      "resolved": "https://registry.npmmirror.com/@esbuild/aix-ppc64/-/aix-ppc64-0.21.5.tgz",
      "integrity": "sha512-1SDgH6ZSPTlggy1yI6+Dbkiz8xzpHJEVAlF/AM1tHPLsf5STom9rwtjE4hKAF20FfXXNTFqEYXyJNWh1GiZedQ==",
      "cpu": [
        "ppc64"
      ],
      "dev": true,
      "optional": true,
      "os": [
        "aix"
      ],
      "engines": {
        "node": ">=12"
      }
    },
    "node_modules/@esbuild/android-arm": {
      "version": "0.21.5",
      "resolved": "https://registry.npmmirror.com/@esbuild/android-arm/-/android-arm-0.21.5.tgz",
      "integrity": "sha512-vCPvzSjpPHEi1siZdlvAlsPxXl7WbOVUBBAowWug4rJHb68Ox8KualB+1ocNvT5fjv6wpkX6o/iEpbDrf68zcg==",
      "cpu": [
        "arm"
      ],
      "dev": true,
      "optional": true,
      "os": [
        "android"
      ],
      "engines": {
        "node": ">=12"
      }
    },
    "node_modules/@esbuild/android-arm64": {
      "version": "0.21.5",
      "resolved": "https://registry.npmmirror.com/@esbuild/android-arm64/-/android-arm64-0.21.5.tgz",
      "integrity": "sha512-c0uX9VAUBQ7dTDCjq+wdyGLowMdtR/GoC2U5IYk/7D1H1JYC0qseD7+11iMP2mRLN9RcCMRcjC4YMclCzGwS/A==",
      "cpu": [
        "arm64"
      ],
      "dev": true,
      "optional": true,
      "os": [
        "android"
      ],
      "engines": {
        "node": ">=12"
      }
    },
    "node_modules/@esbuild/android-x64": {
      "version": "0.21.5",
      "resolved": "https://registry.npmmirror.com/@esbuild/android-x64/-/android-x64-0.21.5.tgz",
      "integrity": "sha512-D7aPRUUNHRBwHxzxRvp856rjUHRFW1SdQATKXH2hqA0kAZb1hKmi02OpYRacl0TxIGz/ZmXWlbZgjwWYaCakTA==",
      "cpu": [
        "x64"
      ],
      "dev": true,
      "optional": true,
      "os": [
        "android"
      ],
      "engines": {
        "node": ">=12"
      }
    },
    "node_modules/@esbuild/darwin-arm64": {
      "version": "0.21.5",
      "resolved": "https://registry.npmmirror.com/@esbuild/darwin-arm64/-/darwin-arm64-0.21.5.tgz",
      "integrity": "sha512-DwqXqZyuk5AiWWf3UfLiRDJ5EDd49zg6O9wclZ7kUMv2WRFr4HKjXp/5t8JZ11QbQfUS6/cRCKGwYhtNAY88kQ==",
      "cpu": [
        "arm64"
      ],
      "dev": true,
      "optional": true,
      "os": [
        "darwin"
      ],
      "engines": {
        "node": ">=12"
      }
    },
    "node_modules/@esbuild/darwin-x64": {
      "version": "0.21.5",
      "resolved": "https://registry.npmmirror.com/@esbuild/darwin-x64/-/darwin-x64-0.21.5.tgz",
      "integrity": "sha512-se/JjF8NlmKVG4kNIuyWMV/22ZaerB+qaSi5MdrXtd6R08kvs2qCN4C09miupktDitvh8jRFflwGFBQcxZRjbw==",
      "cpu": [
        "x64"
      ],
      "dev": true,
      "optional": true,
      "os": [
        "darwin"
      ],
      "engines": {
        "node": ">=12"
      }
    },
    "node_modules/@esbuild/freebsd-arm64": {
      "version": "0.21.5",
      "resolved": "https://registry.npmmirror.com/@esbuild/freebsd-arm64/-/freebsd-arm64-0.21.5.tgz",
      "integrity": "sha512-5JcRxxRDUJLX8JXp/wcBCy3pENnCgBR9bN6JsY4OmhfUtIHe3ZW0mawA7+RDAcMLrMIZaf03NlQiX9DGyB8h4g==",
      "cpu": [
        "arm64"
      ],
      "dev": true,
      "optional": true,
      "os": [
        "freebsd"
      ],
      "engines": {
        "node": ">=12"
      }
    },
    "node_modules/@esbuild/freebsd-x64": {
      "version": "0.21.5",
      "resolved": "https://registry.npmmirror.com/@esbuild/freebsd-x64/-/freebsd-x64-0.21.5.tgz",
      "integrity": "sha512-J95kNBj1zkbMXtHVH29bBriQygMXqoVQOQYA+ISs0/2l3T9/kj42ow2mpqerRBxDJnmkUDCaQT/dfNXWX/ZZCQ==",
      "cpu": [
        "x64"
      ],
      "dev": true,
      "optional": true,
      "os": [
        "freebsd"
      ],
      "engines": {
        "node": ">=12"
      }
    },
    "node_modules/@esbuild/linux-arm": {
      "version": "0.21.5",
      "resolved": "https://registry.npmmirror.com/@esbuild/linux-arm/-/linux-arm-0.21.5.tgz",
      "integrity": "sha512-bPb5AHZtbeNGjCKVZ9UGqGwo8EUu4cLq68E95A53KlxAPRmUyYv2D6F0uUI65XisGOL1hBP5mTronbgo+0bFcA==",
      "cpu": [
        "arm"
      ],
      "dev": true,
      "optional": true,
      "os": [
        "linux"
      ],
      "engines": {
        "node": ">=12"
      }
    },
    "node_modules/@esbuild/linux-arm64": {
      "version": "0.21.5",
      "resolved": "https://registry.npmmirror.com/@esbuild/linux-arm64/-/linux-arm64-0.21.5.tgz",
      "integrity": "sha512-ibKvmyYzKsBeX8d8I7MH/TMfWDXBF3db4qM6sy+7re0YXya+K1cem3on9XgdT2EQGMu4hQyZhan7TeQ8XkGp4Q==",
      "cpu": [
        "arm64"
      ],
      "dev": true,
      "optional": true,
      "os": [
        "linux"
      ],
      "engines": {
        "node": ">=12"
      }
    },
    "node_modules/@esbuild/linux-ia32": {
      "version": "0.21.5",
      "resolved": "https://registry.npmmirror.com/@esbuild/linux-ia32/-/linux-ia32-0.21.5.tgz",
      "integrity": "sha512-YvjXDqLRqPDl2dvRODYmmhz4rPeVKYvppfGYKSNGdyZkA01046pLWyRKKI3ax8fbJoK5QbxblURkwK/MWY18Tg==",
      "cpu": [
        "ia32"
      ],
      "dev": true,
      "optional": true,
      "os": [
        "linux"
      ],
      "engines": {
        "node": ">=12"
      }
    },
    "node_modules/@esbuild/linux-loong64": {
      "version": "0.21.5",
      "resolved": "https://registry.npmmirror.com/@esbuild/linux-loong64/-/linux-loong64-0.21.5.tgz",
      "integrity": "sha512-uHf1BmMG8qEvzdrzAqg2SIG/02+4/DHB6a9Kbya0XDvwDEKCoC8ZRWI5JJvNdUjtciBGFQ5PuBlpEOXQj+JQSg==",
      "cpu": [
        "loong64"
      ],
      "dev": true,
      "optional": true,
      "os": [
        "linux"
      ],
      "engines": {
        "node": ">=12"
      }
    },
    "node_modules/@esbuild/linux-mips64el": {
      "version": "0.21.5",
      "resolved": "https://registry.npmmirror.com/@esbuild/linux-mips64el/-/linux-mips64el-0.21.5.tgz",
      "integrity": "sha512-IajOmO+KJK23bj52dFSNCMsz1QP1DqM6cwLUv3W1QwyxkyIWecfafnI555fvSGqEKwjMXVLokcV5ygHW5b3Jbg==",
      "cpu": [
        "mips64el"
      ],
      "dev": true,
      "optional": true,
      "os": [
        "linux"
      ],
      "engines": {
        "node": ">=12"
      }
    },
    "node_modules/@esbuild/linux-ppc64": {
      "version": "0.21.5",
      "resolved": "https://registry.npmmirror.com/@esbuild/linux-ppc64/-/linux-ppc64-0.21.5.tgz",
      "integrity": "sha512-1hHV/Z4OEfMwpLO8rp7CvlhBDnjsC3CttJXIhBi+5Aj5r+MBvy4egg7wCbe//hSsT+RvDAG7s81tAvpL2XAE4w==",
      "cpu": [
        "ppc64"
      ],
      "dev": true,
      "optional": true,
      "os": [
        "linux"
      ],
      "engines": {
        "node": ">=12"
      }
    },
    "node_modules/@esbuild/linux-riscv64": {
      "version": "0.21.5",
      "resolved": "https://registry.npmmirror.com/@esbuild/linux-riscv64/-/linux-riscv64-0.21.5.tgz",
      "integrity": "sha512-2HdXDMd9GMgTGrPWnJzP2ALSokE/0O5HhTUvWIbD3YdjME8JwvSCnNGBnTThKGEB91OZhzrJ4qIIxk/SBmyDDA==",
      "cpu": [
        "riscv64"
      ],
      "dev": true,
      "optional": true,
      "os": [
        "linux"
      ],
      "engines": {
        "node": ">=12"
      }
    },
    "node_modules/@esbuild/linux-s390x": {
      "version": "0.21.5",
      "resolved": "https://registry.npmmirror.com/@esbuild/linux-s390x/-/linux-s390x-0.21.5.tgz",
      "integrity": "sha512-zus5sxzqBJD3eXxwvjN1yQkRepANgxE9lgOW2qLnmr8ikMTphkjgXu1HR01K4FJg8h1kEEDAqDcZQtbrRnB41A==",
      "cpu": [
        "s390x"
      ],
      "dev": true,
      "optional": true,
      "os": [
        "linux"
      ],
      "engines": {
        "node": ">=12"
      }
    },
    "node_modules/@esbuild/linux-x64": {
      "version": "0.21.5",
      "resolved": "https://registry.npmmirror.com/@esbuild/linux-x64/-/linux-x64-0.21.5.tgz",
      "integrity": "sha512-1rYdTpyv03iycF1+BhzrzQJCdOuAOtaqHTWJZCWvijKD2N5Xu0TtVC8/+1faWqcP9iBCWOmjmhoH94dH82BxPQ==",
      "cpu": [
        "x64"
      ],
      "dev": true,
      "optional": true,
      "os": [
        "linux"
      ],
      "engines": {
        "node": ">=12"
      }
    },
    "node_modules/@esbuild/netbsd-x64": {
      "version": "0.21.5",
      "resolved": "https://registry.npmmirror.com/@esbuild/netbsd-x64/-/netbsd-x64-0.21.5.tgz",
      "integrity": "sha512-Woi2MXzXjMULccIwMnLciyZH4nCIMpWQAs049KEeMvOcNADVxo0UBIQPfSmxB3CWKedngg7sWZdLvLczpe0tLg==",
      "cpu": [
        "x64"
      ],
      "dev": true,
      "optional": true,
      "os": [
        "netbsd"
      ],
      "engines": {
        "node": ">=12"
      }
    },
    "node_modules/@esbuild/openbsd-x64": {
      "version": "0.21.5",
      "resolved": "https://registry.npmmirror.com/@esbuild/openbsd-x64/-/openbsd-x64-0.21.5.tgz",
      "integrity": "sha512-HLNNw99xsvx12lFBUwoT8EVCsSvRNDVxNpjZ7bPn947b8gJPzeHWyNVhFsaerc0n3TsbOINvRP2byTZ5LKezow==",
      "cpu": [
        "x64"
      ],
      "dev": true,
      "optional": true,
      "os": [
        "openbsd"
      ],
      "engines": {
        "node": ">=12"
      }
    },
    "node_modules/@esbuild/sunos-x64": {
      "version": "0.21.5",
      "resolved": "https://registry.npmmirror.com/@esbuild/sunos-x64/-/sunos-x64-0.21.5.tgz",
      "integrity": "sha512-6+gjmFpfy0BHU5Tpptkuh8+uw3mnrvgs+dSPQXQOv3ekbordwnzTVEb4qnIvQcYXq6gzkyTnoZ9dZG+D4garKg==",
      "cpu": [
        "x64"
      ],
      "dev": true,
      "optional": true,
      "os": [
        "sunos"
      ],
      "engines": {
        "node": ">=12"
      }
    },
    "node_modules/@esbuild/win32-arm64": {
      "version": "0.21.5",
      "resolved": "https://registry.npmmirror.com/@esbuild/win32-arm64/-/win32-arm64-0.21.5.tgz",
      "integrity": "sha512-Z0gOTd75VvXqyq7nsl93zwahcTROgqvuAcYDUr+vOv8uHhNSKROyU961kgtCD1e95IqPKSQKH7tBTslnS3tA8A==",
      "cpu": [
        "arm64"
      ],
      "dev": true,
      "optional": true,
      "os": [
        "win32"
      ],
      "engines": {
        "node": ">=12"
      }
    },
    "node_modules/@esbuild/win32-ia32": {
      "version": "0.21.5",
      "resolved": "https://registry.npmmirror.com/@esbuild/win32-ia32/-/win32-ia32-0.21.5.tgz",
      "integrity": "sha512-SWXFF1CL2RVNMaVs+BBClwtfZSvDgtL//G/smwAc5oVK/UPu2Gu9tIaRgFmYFFKrmg3SyAjSrElf0TiJ1v8fYA==",
      "cpu": [
        "ia32"
      ],
      "dev": true,
      "optional": true,
      "os": [
        "win32"
      ],
      "engines": {
        "node": ">=12"
      }
    },
    "node_modules/@esbuild/win32-x64": {
      "version": "0.21.5",
      "resolved": "https://registry.npmmirror.com/@esbuild/win32-x64/-/win32-x64-0.21.5.tgz",
      "integrity": "sha512-tQd/1efJuzPC6rCFwEvLtci/xNFcTZknmXs98FYDfGE4wP9ClFV98nyKrzJKVPMhdDnjzLhdUyMX4PsQAPjwIw==",
      "cpu": [
        "x64"
      ],
      "dev": true,
      "optional": true,
      "os": [
        "win32"
      ],
      "engines": {
        "node": ">=12"
      }
    },
    "node_modules/@floating-ui/core": {
      "version": "1.6.9",
      "resolved": "https://registry.npmmirror.com/@floating-ui/core/-/core-1.6.9.tgz",
      "integrity": "sha512-uMXCuQ3BItDUbAMhIXw7UPXRfAlOAvZzdK9BWpE60MCn+Svt3aLn9jsPTi/WNGlRUu2uI0v5S7JiIUsbsvh3fw==",
      "dependencies": {
        "@floating-ui/utils": "^0.2.9"
      }
    },
    "node_modules/@floating-ui/dom": {
      "version": "1.6.13",
      "resolved": "https://registry.npmmirror.com/@floating-ui/dom/-/dom-1.6.13.tgz",
      "integrity": "sha512-umqzocjDgNRGTuO7Q8CU32dkHkECqI8ZdMZ5Swb6QAM0t5rnlrN3lGo1hdpscRd3WS8T6DKYK4ephgIH9iRh3w==",
      "dependencies": {
        "@floating-ui/core": "^1.6.0",
        "@floating-ui/utils": "^0.2.9"
      }
    },
    "node_modules/@floating-ui/utils": {
      "version": "0.2.9",
      "resolved": "https://registry.npmmirror.com/@floating-ui/utils/-/utils-0.2.9.tgz",
      "integrity": "sha512-MDWhGtE+eHw5JW7lq4qhc5yRLS11ERl1c7Z6Xd0a58DozHES6EnNNwUWbMiG4J9Cgj053Bhk8zvlhFYKVhULwg=="
    },
    "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=="
    },
    "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==",
      "funding": {
        "type": "opencollective",
        "url": "https://opencollective.com/popperjs"
      }
    },
    "node_modules/@rollup/rollup-android-arm-eabi": {
      "version": "4.34.8",
      "resolved": "https://registry.npmmirror.com/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.34.8.tgz",
      "integrity": "sha512-q217OSE8DTp8AFHuNHXo0Y86e1wtlfVrXiAlwkIvGRQv9zbc6mE3sjIVfwI8sYUyNxwOg0j/Vm1RKM04JcWLJw==",
      "cpu": [
        "arm"
      ],
      "dev": true,
      "optional": true,
      "os": [
        "android"
      ]
    },
    "node_modules/@rollup/rollup-android-arm64": {
      "version": "4.34.8",
      "resolved": "https://registry.npmmirror.com/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.34.8.tgz",
      "integrity": "sha512-Gigjz7mNWaOL9wCggvoK3jEIUUbGul656opstjaUSGC3eT0BM7PofdAJaBfPFWWkXNVAXbaQtC99OCg4sJv70Q==",
      "cpu": [
        "arm64"
      ],
      "dev": true,
      "optional": true,
      "os": [
        "android"
      ]
    },
    "node_modules/@rollup/rollup-darwin-arm64": {
      "version": "4.34.8",
      "resolved": "https://registry.npmmirror.com/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.34.8.tgz",
      "integrity": "sha512-02rVdZ5tgdUNRxIUrFdcMBZQoaPMrxtwSb+/hOfBdqkatYHR3lZ2A2EGyHq2sGOd0Owk80oV3snlDASC24He3Q==",
      "cpu": [
        "arm64"
      ],
      "dev": true,
      "optional": true,
      "os": [
        "darwin"
      ]
    },
    "node_modules/@rollup/rollup-darwin-x64": {
      "version": "4.34.8",
      "resolved": "https://registry.npmmirror.com/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.34.8.tgz",
      "integrity": "sha512-qIP/elwR/tq/dYRx3lgwK31jkZvMiD6qUtOycLhTzCvrjbZ3LjQnEM9rNhSGpbLXVJYQ3rq39A6Re0h9tU2ynw==",
      "cpu": [
        "x64"
      ],
      "dev": true,
      "optional": true,
      "os": [
        "darwin"
      ]
    },
    "node_modules/@rollup/rollup-freebsd-arm64": {
      "version": "4.34.8",
      "resolved": "https://registry.npmmirror.com/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.34.8.tgz",
      "integrity": "sha512-IQNVXL9iY6NniYbTaOKdrlVP3XIqazBgJOVkddzJlqnCpRi/yAeSOa8PLcECFSQochzqApIOE1GHNu3pCz+BDA==",
      "cpu": [
        "arm64"
      ],
      "dev": true,
      "optional": true,
      "os": [
        "freebsd"
      ]
    },
    "node_modules/@rollup/rollup-freebsd-x64": {
      "version": "4.34.8",
      "resolved": "https://registry.npmmirror.com/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.34.8.tgz",
      "integrity": "sha512-TYXcHghgnCqYFiE3FT5QwXtOZqDj5GmaFNTNt3jNC+vh22dc/ukG2cG+pi75QO4kACohZzidsq7yKTKwq/Jq7Q==",
      "cpu": [
        "x64"
      ],
      "dev": true,
      "optional": true,
      "os": [
        "freebsd"
      ]
    },
    "node_modules/@rollup/rollup-linux-arm-gnueabihf": {
      "version": "4.34.8",
      "resolved": "https://registry.npmmirror.com/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.34.8.tgz",
      "integrity": "sha512-A4iphFGNkWRd+5m3VIGuqHnG3MVnqKe7Al57u9mwgbyZ2/xF9Jio72MaY7xxh+Y87VAHmGQr73qoKL9HPbXj1g==",
      "cpu": [
        "arm"
      ],
      "dev": true,
      "optional": true,
      "os": [
        "linux"
      ]
    },
    "node_modules/@rollup/rollup-linux-arm-musleabihf": {
      "version": "4.34.8",
      "resolved": "https://registry.npmmirror.com/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.34.8.tgz",
      "integrity": "sha512-S0lqKLfTm5u+QTxlFiAnb2J/2dgQqRy/XvziPtDd1rKZFXHTyYLoVL58M/XFwDI01AQCDIevGLbQrMAtdyanpA==",
      "cpu": [
        "arm"
      ],
      "dev": true,
      "optional": true,
      "os": [
        "linux"
      ]
    },
    "node_modules/@rollup/rollup-linux-arm64-gnu": {
      "version": "4.34.8",
      "resolved": "https://registry.npmmirror.com/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.34.8.tgz",
      "integrity": "sha512-jpz9YOuPiSkL4G4pqKrus0pn9aYwpImGkosRKwNi+sJSkz+WU3anZe6hi73StLOQdfXYXC7hUfsQlTnjMd3s1A==",
      "cpu": [
        "arm64"
      ],
      "dev": true,
      "optional": true,
      "os": [
        "linux"
      ]
    },
    "node_modules/@rollup/rollup-linux-arm64-musl": {
      "version": "4.34.8",
      "resolved": "https://registry.npmmirror.com/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.34.8.tgz",
      "integrity": "sha512-KdSfaROOUJXgTVxJNAZ3KwkRc5nggDk+06P6lgi1HLv1hskgvxHUKZ4xtwHkVYJ1Rep4GNo+uEfycCRRxht7+Q==",
      "cpu": [
        "arm64"
      ],
      "dev": true,
      "optional": true,
      "os": [
        "linux"
      ]
    },
    "node_modules/@rollup/rollup-linux-loongarch64-gnu": {
      "version": "4.34.8",
      "resolved": "https://registry.npmmirror.com/@rollup/rollup-linux-loongarch64-gnu/-/rollup-linux-loongarch64-gnu-4.34.8.tgz",
      "integrity": "sha512-NyF4gcxwkMFRjgXBM6g2lkT58OWztZvw5KkV2K0qqSnUEqCVcqdh2jN4gQrTn/YUpAcNKyFHfoOZEer9nwo6uQ==",
      "cpu": [
        "loong64"
      ],
      "dev": true,
      "optional": true,
      "os": [
        "linux"
      ]
    },
    "node_modules/@rollup/rollup-linux-powerpc64le-gnu": {
      "version": "4.34.8",
      "resolved": "https://registry.npmmirror.com/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.34.8.tgz",
      "integrity": "sha512-LMJc999GkhGvktHU85zNTDImZVUCJ1z/MbAJTnviiWmmjyckP5aQsHtcujMjpNdMZPT2rQEDBlJfubhs3jsMfw==",
      "cpu": [
        "ppc64"
      ],
      "dev": true,
      "optional": true,
      "os": [
        "linux"
      ]
    },
    "node_modules/@rollup/rollup-linux-riscv64-gnu": {
      "version": "4.34.8",
      "resolved": "https://registry.npmmirror.com/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.34.8.tgz",
      "integrity": "sha512-xAQCAHPj8nJq1PI3z8CIZzXuXCstquz7cIOL73HHdXiRcKk8Ywwqtx2wrIy23EcTn4aZ2fLJNBB8d0tQENPCmw==",
      "cpu": [
        "riscv64"
      ],
      "dev": true,
      "optional": true,
      "os": [
        "linux"
      ]
    },
    "node_modules/@rollup/rollup-linux-s390x-gnu": {
      "version": "4.34.8",
      "resolved": "https://registry.npmmirror.com/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.34.8.tgz",
      "integrity": "sha512-DdePVk1NDEuc3fOe3dPPTb+rjMtuFw89gw6gVWxQFAuEqqSdDKnrwzZHrUYdac7A7dXl9Q2Vflxpme15gUWQFA==",
      "cpu": [
        "s390x"
      ],
      "dev": true,
      "optional": true,
      "os": [
        "linux"
      ]
    },
    "node_modules/@rollup/rollup-linux-x64-gnu": {
      "version": "4.34.8",
      "resolved": "https://registry.npmmirror.com/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.34.8.tgz",
      "integrity": "sha512-8y7ED8gjxITUltTUEJLQdgpbPh1sUQ0kMTmufRF/Ns5tI9TNMNlhWtmPKKHCU0SilX+3MJkZ0zERYYGIVBYHIA==",
      "cpu": [
        "x64"
      ],
      "dev": true,
      "optional": true,
      "os": [
        "linux"
      ]
    },
    "node_modules/@rollup/rollup-linux-x64-musl": {
      "version": "4.34.8",
      "resolved": "https://registry.npmmirror.com/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.34.8.tgz",
      "integrity": "sha512-SCXcP0ZpGFIe7Ge+McxY5zKxiEI5ra+GT3QRxL0pMMtxPfpyLAKleZODi1zdRHkz5/BhueUrYtYVgubqe9JBNQ==",
      "cpu": [
        "x64"
      ],
      "dev": true,
      "optional": true,
      "os": [
        "linux"
      ]
    },
    "node_modules/@rollup/rollup-win32-arm64-msvc": {
      "version": "4.34.8",
      "resolved": "https://registry.npmmirror.com/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.34.8.tgz",
      "integrity": "sha512-YHYsgzZgFJzTRbth4h7Or0m5O74Yda+hLin0irAIobkLQFRQd1qWmnoVfwmKm9TXIZVAD0nZ+GEb2ICicLyCnQ==",
      "cpu": [
        "arm64"
      ],
      "dev": true,
      "optional": true,
      "os": [
        "win32"
      ]
    },
    "node_modules/@rollup/rollup-win32-ia32-msvc": {
      "version": "4.34.8",
      "resolved": "https://registry.npmmirror.com/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.34.8.tgz",
      "integrity": "sha512-r3NRQrXkHr4uWy5TOjTpTYojR9XmF0j/RYgKCef+Ag46FWUTltm5ziticv8LdNsDMehjJ543x/+TJAek/xBA2w==",
      "cpu": [
        "ia32"
      ],
      "dev": true,
      "optional": true,
      "os": [
        "win32"
      ]
    },
    "node_modules/@rollup/rollup-win32-x64-msvc": {
      "version": "4.34.8",
      "resolved": "https://registry.npmmirror.com/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.34.8.tgz",
      "integrity": "sha512-U0FaE5O1BCpZSeE6gBl3c5ObhePQSfk9vDRToMmTkbhCOgW4jqvtS5LGyQ76L1fH8sM0keRp4uDTsbjiUyjk0g==",
      "cpu": [
        "x64"
      ],
      "dev": true,
      "optional": true,
      "os": [
        "win32"
      ]
    },
    "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
    },
    "node_modules/@types/lodash": {
      "version": "4.17.15",
      "resolved": "https://registry.npmmirror.com/@types/lodash/-/lodash-4.17.15.tgz",
      "integrity": "sha512-w/P33JFeySuhN6JLkysYUK2gEmy9kHHFN7E8ro0tkfmlDOgxBDzWEZ/J8cWA+fHqFevpswDTFZnDx+R9lbL6xw=="
    },
    "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==",
      "dependencies": {
        "@types/lodash": "*"
      }
    },
    "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=="
    },
    "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,
      "engines": {
        "node": "^18.0.0 || >=20.0.0"
      },
      "peerDependencies": {
        "vite": "^5.0.0 || ^6.0.0",
        "vue": "^3.2.25"
      }
    },
    "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==",
      "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==",
      "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==",
      "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==",
      "dependencies": {
        "@vue/compiler-dom": "3.5.13",
        "@vue/shared": "3.5.13"
      }
    },
    "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=="
    },
    "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==",
      "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==",
      "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==",
      "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==",
      "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=="
    },
    "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==",
      "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/core/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,
      "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/@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==",
      "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==",
      "dependencies": {
        "vue-demi": "*"
      },
      "funding": {
        "url": "https://github.com/sponsors/antfu"
      }
    },
    "node_modules/@vueuse/shared/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,
      "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/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=="
    },
    "node_modules/copy-anything": {
      "version": "2.0.6",
      "resolved": "https://registry.npmmirror.com/copy-anything/-/copy-anything-2.0.6.tgz",
      "integrity": "sha512-1j20GZTsvKNkc4BY3NpMOM8tt///wY3FpIzozTOFO2ffuZcV61nojHXVKIy3WM+7ADCy5FVhdZYHYDdgTU0yJw==",
      "dev": true,
      "dependencies": {
        "is-what": "^3.14.1"
      },
      "funding": {
        "url": "https://github.com/sponsors/mesqueeb"
      }
    },
    "node_modules/csstype": {
      "version": "3.1.3",
      "resolved": "https://registry.npmmirror.com/csstype/-/csstype-3.1.3.tgz",
      "integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw=="
    },
    "node_modules/dayjs": {
      "version": "1.11.13",
      "resolved": "https://registry.npmmirror.com/dayjs/-/dayjs-1.11.13.tgz",
      "integrity": "sha512-oaMBel6gjolK862uaPQOVTA7q3TZhuSvuMQAAglQDOWYO9A91IrAOUJEyKVlqJlHE0vq5p5UXxzdPfMH/x6xNg=="
    },
    "node_modules/element-plus": {
      "version": "2.9.5",
      "resolved": "https://registry.npmmirror.com/element-plus/-/element-plus-2.9.5.tgz",
      "integrity": "sha512-r+X79oogLbYq8p9L5f9fHSHhUFNM0AL72aikqiZVxSc2/08mK6m/PotiB9e/D90QmWTIHIaFnFmW65AcXmneig==",
      "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==",
      "engines": {
        "node": ">=0.12"
      },
      "funding": {
        "url": "https://github.com/fb55/entities?sponsor=1"
      }
    },
    "node_modules/errno": {
      "version": "0.1.8",
      "resolved": "https://registry.npmmirror.com/errno/-/errno-0.1.8.tgz",
      "integrity": "sha512-dJ6oBr5SQ1VSd9qkk7ByRgb/1SH4JZjCHSW/mr63/QcXO9zLVxvJ6Oy13nio03rxpSnVDDjFor75SjVeZWPW/A==",
      "dev": true,
      "optional": true,
      "dependencies": {
        "prr": "~1.0.1"
      },
      "bin": {
        "errno": "cli.js"
      }
    },
    "node_modules/esbuild": {
      "version": "0.21.5",
      "resolved": "https://registry.npmmirror.com/esbuild/-/esbuild-0.21.5.tgz",
      "integrity": "sha512-mg3OPMV4hXywwpoDxu3Qda5xCKQi+vCTZq8S9J/EpkhB2HzKXq4SNFZE3+NK93JYxc8VMSep+lOUSC/RVKaBqw==",
      "dev": true,
      "hasInstallScript": true,
      "bin": {
        "esbuild": "bin/esbuild"
      },
      "engines": {
        "node": ">=12"
      },
      "optionalDependencies": {
        "@esbuild/aix-ppc64": "0.21.5",
        "@esbuild/android-arm": "0.21.5",
        "@esbuild/android-arm64": "0.21.5",
        "@esbuild/android-x64": "0.21.5",
        "@esbuild/darwin-arm64": "0.21.5",
        "@esbuild/darwin-x64": "0.21.5",
        "@esbuild/freebsd-arm64": "0.21.5",
        "@esbuild/freebsd-x64": "0.21.5",
        "@esbuild/linux-arm": "0.21.5",
        "@esbuild/linux-arm64": "0.21.5",
        "@esbuild/linux-ia32": "0.21.5",
        "@esbuild/linux-loong64": "0.21.5",
        "@esbuild/linux-mips64el": "0.21.5",
        "@esbuild/linux-ppc64": "0.21.5",
        "@esbuild/linux-riscv64": "0.21.5",
        "@esbuild/linux-s390x": "0.21.5",
        "@esbuild/linux-x64": "0.21.5",
        "@esbuild/netbsd-x64": "0.21.5",
        "@esbuild/openbsd-x64": "0.21.5",
        "@esbuild/sunos-x64": "0.21.5",
        "@esbuild/win32-arm64": "0.21.5",
        "@esbuild/win32-ia32": "0.21.5",
        "@esbuild/win32-x64": "0.21.5"
      }
    },
    "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=="
    },
    "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=="
    },
    "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,
      "optional": true,
      "os": [
        "darwin"
      ],
      "engines": {
        "node": "^8.16.0 || ^10.6.0 || >=11.0.0"
      }
    },
    "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,
      "optional": true
    },
    "node_modules/iconv-lite": {
      "version": "0.6.3",
      "resolved": "https://registry.npmmirror.com/iconv-lite/-/iconv-lite-0.6.3.tgz",
      "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==",
      "dev": true,
      "optional": true,
      "dependencies": {
        "safer-buffer": ">= 2.1.2 < 3.0.0"
      },
      "engines": {
        "node": ">=0.10.0"
      }
    },
    "node_modules/image-size": {
      "version": "0.5.5",
      "resolved": "https://registry.npmmirror.com/image-size/-/image-size-0.5.5.tgz",
      "integrity": "sha512-6TDAlDPZxUFCv+fuOkIoXT/V/f3Qbq8e37p+YOiYrUv3v9cc3/6x78VdfPgFVaB9dZYeLUfKgHRebpkm/oP2VQ==",
      "dev": true,
      "optional": true,
      "bin": {
        "image-size": "bin/image-size.js"
      },
      "engines": {
        "node": ">=0.10.0"
      }
    },
    "node_modules/is-what": {
      "version": "3.14.1",
      "resolved": "https://registry.npmmirror.com/is-what/-/is-what-3.14.1.tgz",
      "integrity": "sha512-sNxgpk9793nzSs7bA6JQJGeIuRBQhAaNGG77kzYQgMkrID+lS6SlK07K5LaptscDlSaIgH+GPFzf+d75FVxozA==",
      "dev": true
    },
    "node_modules/less": {
      "version": "4.2.2",
      "resolved": "https://registry.npmmirror.com/less/-/less-4.2.2.tgz",
      "integrity": "sha512-tkuLHQlvWUTeQ3doAqnHbNn8T6WX1KA8yvbKG9x4VtKtIjHsVKQZCH11zRgAfbDAXC2UNIg/K9BYAAcEzUIrNg==",
      "dev": true,
      "dependencies": {
        "copy-anything": "^2.0.1",
        "parse-node-version": "^1.0.1",
        "tslib": "^2.3.0"
      },
      "bin": {
        "lessc": "bin/lessc"
      },
      "engines": {
        "node": ">=6"
      },
      "optionalDependencies": {
        "errno": "^0.1.1",
        "graceful-fs": "^4.1.2",
        "image-size": "~0.5.0",
        "make-dir": "^2.1.0",
        "mime": "^1.4.1",
        "needle": "^3.1.0",
        "source-map": "~0.6.0"
      }
    },
    "node_modules/less-loader": {
      "version": "12.2.0",
      "resolved": "https://registry.npmmirror.com/less-loader/-/less-loader-12.2.0.tgz",
      "integrity": "sha512-MYUxjSQSBUQmowc0l5nPieOYwMzGPUaTzB6inNW/bdPEG9zOL3eAAD1Qw5ZxSPk7we5dMojHwNODYMV1hq4EVg==",
      "dev": true,
      "engines": {
        "node": ">= 18.12.0"
      },
      "funding": {
        "type": "opencollective",
        "url": "https://opencollective.com/webpack"
      },
      "peerDependencies": {
        "@rspack/core": "0.x || 1.x",
        "less": "^3.5.0 || ^4.0.0",
        "webpack": "^5.0.0"
      },
      "peerDependenciesMeta": {
        "@rspack/core": {
          "optional": true
        },
        "webpack": {
          "optional": true
        }
      }
    },
    "node_modules/lodash": {
      "version": "4.17.21",
      "resolved": "https://registry.npmmirror.com/lodash/-/lodash-4.17.21.tgz",
      "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg=="
    },
    "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=="
    },
    "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==",
      "peerDependencies": {
        "@types/lodash-es": "*",
        "lodash": "*",
        "lodash-es": "*"
      }
    },
    "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==",
      "dependencies": {
        "@jridgewell/sourcemap-codec": "^1.5.0"
      }
    },
    "node_modules/make-dir": {
      "version": "2.1.0",
      "resolved": "https://registry.npmmirror.com/make-dir/-/make-dir-2.1.0.tgz",
      "integrity": "sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA==",
      "dev": true,
      "optional": true,
      "dependencies": {
        "pify": "^4.0.1",
        "semver": "^5.6.0"
      },
      "engines": {
        "node": ">=6"
      }
    },
    "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=="
    },
    "node_modules/mime": {
      "version": "1.6.0",
      "resolved": "https://registry.npmmirror.com/mime/-/mime-1.6.0.tgz",
      "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==",
      "dev": true,
      "optional": true,
      "bin": {
        "mime": "cli.js"
      },
      "engines": {
        "node": ">=4"
      }
    },
    "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"
        }
      ],
      "bin": {
        "nanoid": "bin/nanoid.cjs"
      },
      "engines": {
        "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1"
      }
    },
    "node_modules/needle": {
      "version": "3.3.1",
      "resolved": "https://registry.npmmirror.com/needle/-/needle-3.3.1.tgz",
      "integrity": "sha512-6k0YULvhpw+RoLNiQCRKOl09Rv1dPLr8hHnVjHqdolKwDrdNyk+Hmrthi4lIGPPz3r39dLx0hsF5s40sZ3Us4Q==",
      "dev": true,
      "optional": true,
      "dependencies": {
        "iconv-lite": "^0.6.3",
        "sax": "^1.2.4"
      },
      "bin": {
        "needle": "bin/needle"
      },
      "engines": {
        "node": ">= 4.4.x"
      }
    },
    "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=="
    },
    "node_modules/parse-node-version": {
      "version": "1.0.1",
      "resolved": "https://registry.npmmirror.com/parse-node-version/-/parse-node-version-1.0.1.tgz",
      "integrity": "sha512-3YHlOa/JgH6Mnpr05jP9eDG254US9ek25LyIxZlDItp2iJtwyaXQb57lBYLdT3MowkUFYEV2XXNAYIPlESvJlA==",
      "dev": true,
      "engines": {
        "node": ">= 0.10"
      }
    },
    "node_modules/picocolors": {
      "version": "1.1.1",
      "resolved": "https://registry.npmmirror.com/picocolors/-/picocolors-1.1.1.tgz",
      "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA=="
    },
    "node_modules/pify": {
      "version": "4.0.1",
      "resolved": "https://registry.npmmirror.com/pify/-/pify-4.0.1.tgz",
      "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==",
      "dev": true,
      "optional": true,
      "engines": {
        "node": ">=6"
      }
    },
    "node_modules/postcss": {
      "version": "8.5.3",
      "resolved": "https://registry.npmmirror.com/postcss/-/postcss-8.5.3.tgz",
      "integrity": "sha512-dle9A3yYxlBSrt8Fu+IpjGT8SY8hN0mlaA6GY8t0P5PjIOZemULz/E2Bnm/2dcUOena75OTNkHI76uZBNUUq3A==",
      "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"
        }
      ],
      "dependencies": {
        "nanoid": "^3.3.8",
        "picocolors": "^1.1.1",
        "source-map-js": "^1.2.1"
      },
      "engines": {
        "node": "^10 || ^12 || >=14"
      }
    },
    "node_modules/prr": {
      "version": "1.0.1",
      "resolved": "https://registry.npmmirror.com/prr/-/prr-1.0.1.tgz",
      "integrity": "sha512-yPw4Sng1gWghHQWj0B3ZggWUm4qVbPwPFcRG8KyxiU7J2OHFSoEHKS+EZ3fv5l1t9CyCiop6l/ZYeWbrgoQejw==",
      "dev": true,
      "optional": true
    },
    "node_modules/rollup": {
      "version": "4.34.8",
      "resolved": "https://registry.npmmirror.com/rollup/-/rollup-4.34.8.tgz",
      "integrity": "sha512-489gTVMzAYdiZHFVA/ig/iYFllCcWFHMvUHI1rpFmkoUtRlQxqh6/yiNqnYibjMZ2b/+FUQwldG+aLsEt6bglQ==",
      "dev": true,
      "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.34.8",
        "@rollup/rollup-android-arm64": "4.34.8",
        "@rollup/rollup-darwin-arm64": "4.34.8",
        "@rollup/rollup-darwin-x64": "4.34.8",
        "@rollup/rollup-freebsd-arm64": "4.34.8",
        "@rollup/rollup-freebsd-x64": "4.34.8",
        "@rollup/rollup-linux-arm-gnueabihf": "4.34.8",
        "@rollup/rollup-linux-arm-musleabihf": "4.34.8",
        "@rollup/rollup-linux-arm64-gnu": "4.34.8",
        "@rollup/rollup-linux-arm64-musl": "4.34.8",
        "@rollup/rollup-linux-loongarch64-gnu": "4.34.8",
        "@rollup/rollup-linux-powerpc64le-gnu": "4.34.8",
        "@rollup/rollup-linux-riscv64-gnu": "4.34.8",
        "@rollup/rollup-linux-s390x-gnu": "4.34.8",
        "@rollup/rollup-linux-x64-gnu": "4.34.8",
        "@rollup/rollup-linux-x64-musl": "4.34.8",
        "@rollup/rollup-win32-arm64-msvc": "4.34.8",
        "@rollup/rollup-win32-ia32-msvc": "4.34.8",
        "@rollup/rollup-win32-x64-msvc": "4.34.8",
        "fsevents": "~2.3.2"
      }
    },
    "node_modules/safer-buffer": {
      "version": "2.1.2",
      "resolved": "https://registry.npmmirror.com/safer-buffer/-/safer-buffer-2.1.2.tgz",
      "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==",
      "dev": true,
      "optional": true
    },
    "node_modules/sax": {
      "version": "1.4.1",
      "resolved": "https://registry.npmmirror.com/sax/-/sax-1.4.1.tgz",
      "integrity": "sha512-+aWOz7yVScEGoKNd4PA10LZ8sk0A/z5+nXQG5giUO5rprX9jgYsTdov9qCchZiPIZezbZH+jRut8nPodFAX4Jg==",
      "dev": true,
      "optional": true
    },
    "node_modules/semver": {
      "version": "5.7.2",
      "resolved": "https://registry.npmmirror.com/semver/-/semver-5.7.2.tgz",
      "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==",
      "dev": true,
      "optional": true,
      "bin": {
        "semver": "bin/semver"
      }
    },
    "node_modules/source-map": {
      "version": "0.6.1",
      "resolved": "https://registry.npmmirror.com/source-map/-/source-map-0.6.1.tgz",
      "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
      "dev": true,
      "optional": true,
      "engines": {
        "node": ">=0.10.0"
      }
    },
    "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==",
      "engines": {
        "node": ">=0.10.0"
      }
    },
    "node_modules/tslib": {
      "version": "2.8.1",
      "resolved": "https://registry.npmmirror.com/tslib/-/tslib-2.8.1.tgz",
      "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==",
      "dev": true
    },
    "node_modules/vite": {
      "version": "5.4.14",
      "resolved": "https://registry.npmmirror.com/vite/-/vite-5.4.14.tgz",
      "integrity": "sha512-EK5cY7Q1D8JNhSaPKVK4pwBFvaTmZxEnoKXLG/U9gmdDcihQGNzFlgIvaxezFR4glP1LsuiedwMBqCXH3wZccA==",
      "dev": true,
      "dependencies": {
        "esbuild": "^0.21.3",
        "postcss": "^8.4.43",
        "rollup": "^4.20.0"
      },
      "bin": {
        "vite": "bin/vite.js"
      },
      "engines": {
        "node": "^18.0.0 || >=20.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",
        "less": "*",
        "lightningcss": "^1.21.0",
        "sass": "*",
        "sass-embedded": "*",
        "stylus": "*",
        "sugarss": "*",
        "terser": "^5.4.0"
      },
      "peerDependenciesMeta": {
        "@types/node": {
          "optional": true
        },
        "less": {
          "optional": true
        },
        "lightningcss": {
          "optional": true
        },
        "sass": {
          "optional": true
        },
        "sass-embedded": {
          "optional": true
        },
        "stylus": {
          "optional": true
        },
        "sugarss": {
          "optional": true
        },
        "terser": {
          "optional": true
        }
      }
    },
    "node_modules/vue": {
      "version": "3.5.13",
      "resolved": "https://registry.npmmirror.com/vue/-/vue-3.5.13.tgz",
      "integrity": "sha512-wmeiSMxkZCSc+PM2w2VRsOYAZC8GdipNFRTsLSfodVqI9mbejKeXEGr8SckuLnrQPGe3oJN5c3K0vpoU9q/wCQ==",
      "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-router": {
      "version": "4.5.0",
      "resolved": "https://registry.npmmirror.com/vue-router/-/vue-router-4.5.0.tgz",
      "integrity": "sha512-HDuk+PuH5monfNuY+ct49mNmkCRK4xJAV9Ts4z9UFc4rzdDnxQLyCMGGc8pKhZhHTVzfanpNwB/lwqevcBwI4w==",
      "dependencies": {
        "@vue/devtools-api": "^6.6.4"
      },
      "funding": {
        "url": "https://github.com/sponsors/posva"
      },
      "peerDependencies": {
        "vue": "^3.2.0"
      }
    }
  },
  "dependencies": {
    "@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=="
    },
    "@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=="
    },
    "@babel/parser": {
      "version": "7.26.9",
      "resolved": "https://registry.npmmirror.com/@babel/parser/-/parser-7.26.9.tgz",
      "integrity": "sha512-81NWa1njQblgZbQHxWHpxxCzNsa3ZwvFqpUg7P+NNUU6f3UU2jBEg4OlF/J6rl8+PQGh1q6/zWScd001YwcA5A==",
      "requires": {
        "@babel/types": "^7.26.9"
      }
    },
    "@babel/types": {
      "version": "7.26.9",
      "resolved": "https://registry.npmmirror.com/@babel/types/-/types-7.26.9.tgz",
      "integrity": "sha512-Y3IR1cRnOxOCDvMmNiym7XpXQ93iGDDPHx+Zj+NM+rg0fBaShfQLkg+hKPaZCEvg5N/LeCo4+Rj/i3FuJsIQaw==",
      "requires": {
        "@babel/helper-string-parser": "^7.25.9",
        "@babel/helper-validator-identifier": "^7.25.9"
      }
    },
    "@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=="
    },
    "@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==",
      "requires": {}
    },
    "@esbuild/aix-ppc64": {
      "version": "0.21.5",
      "resolved": "https://registry.npmmirror.com/@esbuild/aix-ppc64/-/aix-ppc64-0.21.5.tgz",
      "integrity": "sha512-1SDgH6ZSPTlggy1yI6+Dbkiz8xzpHJEVAlF/AM1tHPLsf5STom9rwtjE4hKAF20FfXXNTFqEYXyJNWh1GiZedQ==",
      "dev": true,
      "optional": true
    },
    "@esbuild/android-arm": {
      "version": "0.21.5",
      "resolved": "https://registry.npmmirror.com/@esbuild/android-arm/-/android-arm-0.21.5.tgz",
      "integrity": "sha512-vCPvzSjpPHEi1siZdlvAlsPxXl7WbOVUBBAowWug4rJHb68Ox8KualB+1ocNvT5fjv6wpkX6o/iEpbDrf68zcg==",
      "dev": true,
      "optional": true
    },
    "@esbuild/android-arm64": {
      "version": "0.21.5",
      "resolved": "https://registry.npmmirror.com/@esbuild/android-arm64/-/android-arm64-0.21.5.tgz",
      "integrity": "sha512-c0uX9VAUBQ7dTDCjq+wdyGLowMdtR/GoC2U5IYk/7D1H1JYC0qseD7+11iMP2mRLN9RcCMRcjC4YMclCzGwS/A==",
      "dev": true,
      "optional": true
    },
    "@esbuild/android-x64": {
      "version": "0.21.5",
      "resolved": "https://registry.npmmirror.com/@esbuild/android-x64/-/android-x64-0.21.5.tgz",
      "integrity": "sha512-D7aPRUUNHRBwHxzxRvp856rjUHRFW1SdQATKXH2hqA0kAZb1hKmi02OpYRacl0TxIGz/ZmXWlbZgjwWYaCakTA==",
      "dev": true,
      "optional": true
    },
    "@esbuild/darwin-arm64": {
      "version": "0.21.5",
      "resolved": "https://registry.npmmirror.com/@esbuild/darwin-arm64/-/darwin-arm64-0.21.5.tgz",
      "integrity": "sha512-DwqXqZyuk5AiWWf3UfLiRDJ5EDd49zg6O9wclZ7kUMv2WRFr4HKjXp/5t8JZ11QbQfUS6/cRCKGwYhtNAY88kQ==",
      "dev": true,
      "optional": true
    },
    "@esbuild/darwin-x64": {
      "version": "0.21.5",
      "resolved": "https://registry.npmmirror.com/@esbuild/darwin-x64/-/darwin-x64-0.21.5.tgz",
      "integrity": "sha512-se/JjF8NlmKVG4kNIuyWMV/22ZaerB+qaSi5MdrXtd6R08kvs2qCN4C09miupktDitvh8jRFflwGFBQcxZRjbw==",
      "dev": true,
      "optional": true
    },
    "@esbuild/freebsd-arm64": {
      "version": "0.21.5",
      "resolved": "https://registry.npmmirror.com/@esbuild/freebsd-arm64/-/freebsd-arm64-0.21.5.tgz",
      "integrity": "sha512-5JcRxxRDUJLX8JXp/wcBCy3pENnCgBR9bN6JsY4OmhfUtIHe3ZW0mawA7+RDAcMLrMIZaf03NlQiX9DGyB8h4g==",
      "dev": true,
      "optional": true
    },
    "@esbuild/freebsd-x64": {
      "version": "0.21.5",
      "resolved": "https://registry.npmmirror.com/@esbuild/freebsd-x64/-/freebsd-x64-0.21.5.tgz",
      "integrity": "sha512-J95kNBj1zkbMXtHVH29bBriQygMXqoVQOQYA+ISs0/2l3T9/kj42ow2mpqerRBxDJnmkUDCaQT/dfNXWX/ZZCQ==",
      "dev": true,
      "optional": true
    },
    "@esbuild/linux-arm": {
      "version": "0.21.5",
      "resolved": "https://registry.npmmirror.com/@esbuild/linux-arm/-/linux-arm-0.21.5.tgz",
      "integrity": "sha512-bPb5AHZtbeNGjCKVZ9UGqGwo8EUu4cLq68E95A53KlxAPRmUyYv2D6F0uUI65XisGOL1hBP5mTronbgo+0bFcA==",
      "dev": true,
      "optional": true
    },
    "@esbuild/linux-arm64": {
      "version": "0.21.5",
      "resolved": "https://registry.npmmirror.com/@esbuild/linux-arm64/-/linux-arm64-0.21.5.tgz",
      "integrity": "sha512-ibKvmyYzKsBeX8d8I7MH/TMfWDXBF3db4qM6sy+7re0YXya+K1cem3on9XgdT2EQGMu4hQyZhan7TeQ8XkGp4Q==",
      "dev": true,
      "optional": true
    },
    "@esbuild/linux-ia32": {
      "version": "0.21.5",
      "resolved": "https://registry.npmmirror.com/@esbuild/linux-ia32/-/linux-ia32-0.21.5.tgz",
      "integrity": "sha512-YvjXDqLRqPDl2dvRODYmmhz4rPeVKYvppfGYKSNGdyZkA01046pLWyRKKI3ax8fbJoK5QbxblURkwK/MWY18Tg==",
      "dev": true,
      "optional": true
    },
    "@esbuild/linux-loong64": {
      "version": "0.21.5",
      "resolved": "https://registry.npmmirror.com/@esbuild/linux-loong64/-/linux-loong64-0.21.5.tgz",
      "integrity": "sha512-uHf1BmMG8qEvzdrzAqg2SIG/02+4/DHB6a9Kbya0XDvwDEKCoC8ZRWI5JJvNdUjtciBGFQ5PuBlpEOXQj+JQSg==",
      "dev": true,
      "optional": true
    },
    "@esbuild/linux-mips64el": {
      "version": "0.21.5",
      "resolved": "https://registry.npmmirror.com/@esbuild/linux-mips64el/-/linux-mips64el-0.21.5.tgz",
      "integrity": "sha512-IajOmO+KJK23bj52dFSNCMsz1QP1DqM6cwLUv3W1QwyxkyIWecfafnI555fvSGqEKwjMXVLokcV5ygHW5b3Jbg==",
      "dev": true,
      "optional": true
    },
    "@esbuild/linux-ppc64": {
      "version": "0.21.5",
      "resolved": "https://registry.npmmirror.com/@esbuild/linux-ppc64/-/linux-ppc64-0.21.5.tgz",
      "integrity": "sha512-1hHV/Z4OEfMwpLO8rp7CvlhBDnjsC3CttJXIhBi+5Aj5r+MBvy4egg7wCbe//hSsT+RvDAG7s81tAvpL2XAE4w==",
      "dev": true,
      "optional": true
    },
    "@esbuild/linux-riscv64": {
      "version": "0.21.5",
      "resolved": "https://registry.npmmirror.com/@esbuild/linux-riscv64/-/linux-riscv64-0.21.5.tgz",
      "integrity": "sha512-2HdXDMd9GMgTGrPWnJzP2ALSokE/0O5HhTUvWIbD3YdjME8JwvSCnNGBnTThKGEB91OZhzrJ4qIIxk/SBmyDDA==",
      "dev": true,
      "optional": true
    },
    "@esbuild/linux-s390x": {
      "version": "0.21.5",
      "resolved": "https://registry.npmmirror.com/@esbuild/linux-s390x/-/linux-s390x-0.21.5.tgz",
      "integrity": "sha512-zus5sxzqBJD3eXxwvjN1yQkRepANgxE9lgOW2qLnmr8ikMTphkjgXu1HR01K4FJg8h1kEEDAqDcZQtbrRnB41A==",
      "dev": true,
      "optional": true
    },
    "@esbuild/linux-x64": {
      "version": "0.21.5",
      "resolved": "https://registry.npmmirror.com/@esbuild/linux-x64/-/linux-x64-0.21.5.tgz",
      "integrity": "sha512-1rYdTpyv03iycF1+BhzrzQJCdOuAOtaqHTWJZCWvijKD2N5Xu0TtVC8/+1faWqcP9iBCWOmjmhoH94dH82BxPQ==",
      "dev": true,
      "optional": true
    },
    "@esbuild/netbsd-x64": {
      "version": "0.21.5",
      "resolved": "https://registry.npmmirror.com/@esbuild/netbsd-x64/-/netbsd-x64-0.21.5.tgz",
      "integrity": "sha512-Woi2MXzXjMULccIwMnLciyZH4nCIMpWQAs049KEeMvOcNADVxo0UBIQPfSmxB3CWKedngg7sWZdLvLczpe0tLg==",
      "dev": true,
      "optional": true
    },
    "@esbuild/openbsd-x64": {
      "version": "0.21.5",
      "resolved": "https://registry.npmmirror.com/@esbuild/openbsd-x64/-/openbsd-x64-0.21.5.tgz",
      "integrity": "sha512-HLNNw99xsvx12lFBUwoT8EVCsSvRNDVxNpjZ7bPn947b8gJPzeHWyNVhFsaerc0n3TsbOINvRP2byTZ5LKezow==",
      "dev": true,
      "optional": true
    },
    "@esbuild/sunos-x64": {
      "version": "0.21.5",
      "resolved": "https://registry.npmmirror.com/@esbuild/sunos-x64/-/sunos-x64-0.21.5.tgz",
      "integrity": "sha512-6+gjmFpfy0BHU5Tpptkuh8+uw3mnrvgs+dSPQXQOv3ekbordwnzTVEb4qnIvQcYXq6gzkyTnoZ9dZG+D4garKg==",
      "dev": true,
      "optional": true
    },
    "@esbuild/win32-arm64": {
      "version": "0.21.5",
      "resolved": "https://registry.npmmirror.com/@esbuild/win32-arm64/-/win32-arm64-0.21.5.tgz",
      "integrity": "sha512-Z0gOTd75VvXqyq7nsl93zwahcTROgqvuAcYDUr+vOv8uHhNSKROyU961kgtCD1e95IqPKSQKH7tBTslnS3tA8A==",
      "dev": true,
      "optional": true
    },
    "@esbuild/win32-ia32": {
      "version": "0.21.5",
      "resolved": "https://registry.npmmirror.com/@esbuild/win32-ia32/-/win32-ia32-0.21.5.tgz",
      "integrity": "sha512-SWXFF1CL2RVNMaVs+BBClwtfZSvDgtL//G/smwAc5oVK/UPu2Gu9tIaRgFmYFFKrmg3SyAjSrElf0TiJ1v8fYA==",
      "dev": true,
      "optional": true
    },
    "@esbuild/win32-x64": {
      "version": "0.21.5",
      "resolved": "https://registry.npmmirror.com/@esbuild/win32-x64/-/win32-x64-0.21.5.tgz",
      "integrity": "sha512-tQd/1efJuzPC6rCFwEvLtci/xNFcTZknmXs98FYDfGE4wP9ClFV98nyKrzJKVPMhdDnjzLhdUyMX4PsQAPjwIw==",
      "dev": true,
      "optional": true
    },
    "@floating-ui/core": {
      "version": "1.6.9",
      "resolved": "https://registry.npmmirror.com/@floating-ui/core/-/core-1.6.9.tgz",
      "integrity": "sha512-uMXCuQ3BItDUbAMhIXw7UPXRfAlOAvZzdK9BWpE60MCn+Svt3aLn9jsPTi/WNGlRUu2uI0v5S7JiIUsbsvh3fw==",
      "requires": {
        "@floating-ui/utils": "^0.2.9"
      }
    },
    "@floating-ui/dom": {
      "version": "1.6.13",
      "resolved": "https://registry.npmmirror.com/@floating-ui/dom/-/dom-1.6.13.tgz",
      "integrity": "sha512-umqzocjDgNRGTuO7Q8CU32dkHkECqI8ZdMZ5Swb6QAM0t5rnlrN3lGo1hdpscRd3WS8T6DKYK4ephgIH9iRh3w==",
      "requires": {
        "@floating-ui/core": "^1.6.0",
        "@floating-ui/utils": "^0.2.9"
      }
    },
    "@floating-ui/utils": {
      "version": "0.2.9",
      "resolved": "https://registry.npmmirror.com/@floating-ui/utils/-/utils-0.2.9.tgz",
      "integrity": "sha512-MDWhGtE+eHw5JW7lq4qhc5yRLS11ERl1c7Z6Xd0a58DozHES6EnNNwUWbMiG4J9Cgj053Bhk8zvlhFYKVhULwg=="
    },
    "@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=="
    },
    "@popperjs/core": {
      "version": "npm:@sxzz/popperjs-es@2.11.7",
      "resolved": "https://registry.npmmirror.com/@sxzz/popperjs-es/-/popperjs-es-2.11.7.tgz",
      "integrity": "sha512-Ccy0NlLkzr0Ex2FKvh2X+OyERHXJ88XJ1MXtsI9y9fGexlaXaVTPzBCRBwIxFkORuOb+uBqeu+RqnpgYTEZRUQ=="
    },
    "@rollup/rollup-android-arm-eabi": {
      "version": "4.34.8",
      "resolved": "https://registry.npmmirror.com/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.34.8.tgz",
      "integrity": "sha512-q217OSE8DTp8AFHuNHXo0Y86e1wtlfVrXiAlwkIvGRQv9zbc6mE3sjIVfwI8sYUyNxwOg0j/Vm1RKM04JcWLJw==",
      "dev": true,
      "optional": true
    },
    "@rollup/rollup-android-arm64": {
      "version": "4.34.8",
      "resolved": "https://registry.npmmirror.com/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.34.8.tgz",
      "integrity": "sha512-Gigjz7mNWaOL9wCggvoK3jEIUUbGul656opstjaUSGC3eT0BM7PofdAJaBfPFWWkXNVAXbaQtC99OCg4sJv70Q==",
      "dev": true,
      "optional": true
    },
    "@rollup/rollup-darwin-arm64": {
      "version": "4.34.8",
      "resolved": "https://registry.npmmirror.com/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.34.8.tgz",
      "integrity": "sha512-02rVdZ5tgdUNRxIUrFdcMBZQoaPMrxtwSb+/hOfBdqkatYHR3lZ2A2EGyHq2sGOd0Owk80oV3snlDASC24He3Q==",
      "dev": true,
      "optional": true
    },
    "@rollup/rollup-darwin-x64": {
      "version": "4.34.8",
      "resolved": "https://registry.npmmirror.com/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.34.8.tgz",
      "integrity": "sha512-qIP/elwR/tq/dYRx3lgwK31jkZvMiD6qUtOycLhTzCvrjbZ3LjQnEM9rNhSGpbLXVJYQ3rq39A6Re0h9tU2ynw==",
      "dev": true,
      "optional": true
    },
    "@rollup/rollup-freebsd-arm64": {
      "version": "4.34.8",
      "resolved": "https://registry.npmmirror.com/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.34.8.tgz",
      "integrity": "sha512-IQNVXL9iY6NniYbTaOKdrlVP3XIqazBgJOVkddzJlqnCpRi/yAeSOa8PLcECFSQochzqApIOE1GHNu3pCz+BDA==",
      "dev": true,
      "optional": true
    },
    "@rollup/rollup-freebsd-x64": {
      "version": "4.34.8",
      "resolved": "https://registry.npmmirror.com/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.34.8.tgz",
      "integrity": "sha512-TYXcHghgnCqYFiE3FT5QwXtOZqDj5GmaFNTNt3jNC+vh22dc/ukG2cG+pi75QO4kACohZzidsq7yKTKwq/Jq7Q==",
      "dev": true,
      "optional": true
    },
    "@rollup/rollup-linux-arm-gnueabihf": {
      "version": "4.34.8",
      "resolved": "https://registry.npmmirror.com/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.34.8.tgz",
      "integrity": "sha512-A4iphFGNkWRd+5m3VIGuqHnG3MVnqKe7Al57u9mwgbyZ2/xF9Jio72MaY7xxh+Y87VAHmGQr73qoKL9HPbXj1g==",
      "dev": true,
      "optional": true
    },
    "@rollup/rollup-linux-arm-musleabihf": {
      "version": "4.34.8",
      "resolved": "https://registry.npmmirror.com/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.34.8.tgz",
      "integrity": "sha512-S0lqKLfTm5u+QTxlFiAnb2J/2dgQqRy/XvziPtDd1rKZFXHTyYLoVL58M/XFwDI01AQCDIevGLbQrMAtdyanpA==",
      "dev": true,
      "optional": true
    },
    "@rollup/rollup-linux-arm64-gnu": {
      "version": "4.34.8",
      "resolved": "https://registry.npmmirror.com/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.34.8.tgz",
      "integrity": "sha512-jpz9YOuPiSkL4G4pqKrus0pn9aYwpImGkosRKwNi+sJSkz+WU3anZe6hi73StLOQdfXYXC7hUfsQlTnjMd3s1A==",
      "dev": true,
      "optional": true
    },
    "@rollup/rollup-linux-arm64-musl": {
      "version": "4.34.8",
      "resolved": "https://registry.npmmirror.com/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.34.8.tgz",
      "integrity": "sha512-KdSfaROOUJXgTVxJNAZ3KwkRc5nggDk+06P6lgi1HLv1hskgvxHUKZ4xtwHkVYJ1Rep4GNo+uEfycCRRxht7+Q==",
      "dev": true,
      "optional": true
    },
    "@rollup/rollup-linux-loongarch64-gnu": {
      "version": "4.34.8",
      "resolved": "https://registry.npmmirror.com/@rollup/rollup-linux-loongarch64-gnu/-/rollup-linux-loongarch64-gnu-4.34.8.tgz",
      "integrity": "sha512-NyF4gcxwkMFRjgXBM6g2lkT58OWztZvw5KkV2K0qqSnUEqCVcqdh2jN4gQrTn/YUpAcNKyFHfoOZEer9nwo6uQ==",
      "dev": true,
      "optional": true
    },
    "@rollup/rollup-linux-powerpc64le-gnu": {
      "version": "4.34.8",
      "resolved": "https://registry.npmmirror.com/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.34.8.tgz",
      "integrity": "sha512-LMJc999GkhGvktHU85zNTDImZVUCJ1z/MbAJTnviiWmmjyckP5aQsHtcujMjpNdMZPT2rQEDBlJfubhs3jsMfw==",
      "dev": true,
      "optional": true
    },
    "@rollup/rollup-linux-riscv64-gnu": {
      "version": "4.34.8",
      "resolved": "https://registry.npmmirror.com/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.34.8.tgz",
      "integrity": "sha512-xAQCAHPj8nJq1PI3z8CIZzXuXCstquz7cIOL73HHdXiRcKk8Ywwqtx2wrIy23EcTn4aZ2fLJNBB8d0tQENPCmw==",
      "dev": true,
      "optional": true
    },
    "@rollup/rollup-linux-s390x-gnu": {
      "version": "4.34.8",
      "resolved": "https://registry.npmmirror.com/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.34.8.tgz",
      "integrity": "sha512-DdePVk1NDEuc3fOe3dPPTb+rjMtuFw89gw6gVWxQFAuEqqSdDKnrwzZHrUYdac7A7dXl9Q2Vflxpme15gUWQFA==",
      "dev": true,
      "optional": true
    },
    "@rollup/rollup-linux-x64-gnu": {
      "version": "4.34.8",
      "resolved": "https://registry.npmmirror.com/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.34.8.tgz",
      "integrity": "sha512-8y7ED8gjxITUltTUEJLQdgpbPh1sUQ0kMTmufRF/Ns5tI9TNMNlhWtmPKKHCU0SilX+3MJkZ0zERYYGIVBYHIA==",
      "dev": true,
      "optional": true
    },
    "@rollup/rollup-linux-x64-musl": {
      "version": "4.34.8",
      "resolved": "https://registry.npmmirror.com/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.34.8.tgz",
      "integrity": "sha512-SCXcP0ZpGFIe7Ge+McxY5zKxiEI5ra+GT3QRxL0pMMtxPfpyLAKleZODi1zdRHkz5/BhueUrYtYVgubqe9JBNQ==",
      "dev": true,
      "optional": true
    },
    "@rollup/rollup-win32-arm64-msvc": {
      "version": "4.34.8",
      "resolved": "https://registry.npmmirror.com/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.34.8.tgz",
      "integrity": "sha512-YHYsgzZgFJzTRbth4h7Or0m5O74Yda+hLin0irAIobkLQFRQd1qWmnoVfwmKm9TXIZVAD0nZ+GEb2ICicLyCnQ==",
      "dev": true,
      "optional": true
    },
    "@rollup/rollup-win32-ia32-msvc": {
      "version": "4.34.8",
      "resolved": "https://registry.npmmirror.com/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.34.8.tgz",
      "integrity": "sha512-r3NRQrXkHr4uWy5TOjTpTYojR9XmF0j/RYgKCef+Ag46FWUTltm5ziticv8LdNsDMehjJ543x/+TJAek/xBA2w==",
      "dev": true,
      "optional": true
    },
    "@rollup/rollup-win32-x64-msvc": {
      "version": "4.34.8",
      "resolved": "https://registry.npmmirror.com/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.34.8.tgz",
      "integrity": "sha512-U0FaE5O1BCpZSeE6gBl3c5ObhePQSfk9vDRToMmTkbhCOgW4jqvtS5LGyQ76L1fH8sM0keRp4uDTsbjiUyjk0g==",
      "dev": true,
      "optional": true
    },
    "@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
    },
    "@types/lodash": {
      "version": "4.17.15",
      "resolved": "https://registry.npmmirror.com/@types/lodash/-/lodash-4.17.15.tgz",
      "integrity": "sha512-w/P33JFeySuhN6JLkysYUK2gEmy9kHHFN7E8ro0tkfmlDOgxBDzWEZ/J8cWA+fHqFevpswDTFZnDx+R9lbL6xw=="
    },
    "@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==",
      "requires": {
        "@types/lodash": "*"
      }
    },
    "@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=="
    },
    "@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,
      "requires": {}
    },
    "@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==",
      "requires": {
        "@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"
      }
    },
    "@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==",
      "requires": {
        "@vue/compiler-core": "3.5.13",
        "@vue/shared": "3.5.13"
      }
    },
    "@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==",
      "requires": {
        "@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"
      }
    },
    "@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==",
      "requires": {
        "@vue/compiler-dom": "3.5.13",
        "@vue/shared": "3.5.13"
      }
    },
    "@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=="
    },
    "@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==",
      "requires": {
        "@vue/shared": "3.5.13"
      }
    },
    "@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==",
      "requires": {
        "@vue/reactivity": "3.5.13",
        "@vue/shared": "3.5.13"
      }
    },
    "@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==",
      "requires": {
        "@vue/reactivity": "3.5.13",
        "@vue/runtime-core": "3.5.13",
        "@vue/shared": "3.5.13",
        "csstype": "^3.1.3"
      }
    },
    "@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==",
      "requires": {
        "@vue/compiler-ssr": "3.5.13",
        "@vue/shared": "3.5.13"
      }
    },
    "@vue/shared": {
      "version": "3.5.13",
      "resolved": "https://registry.npmmirror.com/@vue/shared/-/shared-3.5.13.tgz",
      "integrity": "sha512-/hnE/qP5ZoGpol0a5mDi45bOd7t3tjYJBjsgCsivow7D48cJeV5l05RD82lPqi7gRiphZM37rnhW1l6ZoCNNnQ=="
    },
    "@vueuse/core": {
      "version": "9.13.0",
      "resolved": "https://registry.npmmirror.com/@vueuse/core/-/core-9.13.0.tgz",
      "integrity": "sha512-pujnclbeHWxxPRqXWmdkKV5OX4Wk4YeK7wusHqRwU0Q7EFusHoqNA/aPhB6KCh9hEqJkLAJo7bb0Lh9b+OIVzw==",
      "requires": {
        "@types/web-bluetooth": "^0.0.16",
        "@vueuse/metadata": "9.13.0",
        "@vueuse/shared": "9.13.0",
        "vue-demi": "*"
      },
      "dependencies": {
        "vue-demi": {
          "version": "0.14.10",
          "resolved": "https://registry.npmmirror.com/vue-demi/-/vue-demi-0.14.10.tgz",
          "integrity": "sha512-nMZBOwuzabUO0nLgIcc6rycZEebF6eeUfaiQx9+WSk8e29IbLvPU9feI6tqW4kTo3hvoYAJkMh8n8D0fuISphg==",
          "requires": {}
        }
      }
    },
    "@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=="
    },
    "@vueuse/shared": {
      "version": "9.13.0",
      "resolved": "https://registry.npmmirror.com/@vueuse/shared/-/shared-9.13.0.tgz",
      "integrity": "sha512-UrnhU+Cnufu4S6JLCPZnkWh0WwZGUp72ktOF2DFptMlOs3TOdVv8xJN53zhHGARmVOsz5KqOls09+J1NR6sBKw==",
      "requires": {
        "vue-demi": "*"
      },
      "dependencies": {
        "vue-demi": {
          "version": "0.14.10",
          "resolved": "https://registry.npmmirror.com/vue-demi/-/vue-demi-0.14.10.tgz",
          "integrity": "sha512-nMZBOwuzabUO0nLgIcc6rycZEebF6eeUfaiQx9+WSk8e29IbLvPU9feI6tqW4kTo3hvoYAJkMh8n8D0fuISphg==",
          "requires": {}
        }
      }
    },
    "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=="
    },
    "copy-anything": {
      "version": "2.0.6",
      "resolved": "https://registry.npmmirror.com/copy-anything/-/copy-anything-2.0.6.tgz",
      "integrity": "sha512-1j20GZTsvKNkc4BY3NpMOM8tt///wY3FpIzozTOFO2ffuZcV61nojHXVKIy3WM+7ADCy5FVhdZYHYDdgTU0yJw==",
      "dev": true,
      "requires": {
        "is-what": "^3.14.1"
      }
    },
    "csstype": {
      "version": "3.1.3",
      "resolved": "https://registry.npmmirror.com/csstype/-/csstype-3.1.3.tgz",
      "integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw=="
    },
    "dayjs": {
      "version": "1.11.13",
      "resolved": "https://registry.npmmirror.com/dayjs/-/dayjs-1.11.13.tgz",
      "integrity": "sha512-oaMBel6gjolK862uaPQOVTA7q3TZhuSvuMQAAglQDOWYO9A91IrAOUJEyKVlqJlHE0vq5p5UXxzdPfMH/x6xNg=="
    },
    "element-plus": {
      "version": "2.9.5",
      "resolved": "https://registry.npmmirror.com/element-plus/-/element-plus-2.9.5.tgz",
      "integrity": "sha512-r+X79oogLbYq8p9L5f9fHSHhUFNM0AL72aikqiZVxSc2/08mK6m/PotiB9e/D90QmWTIHIaFnFmW65AcXmneig==",
      "requires": {
        "@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"
      }
    },
    "entities": {
      "version": "4.5.0",
      "resolved": "https://registry.npmmirror.com/entities/-/entities-4.5.0.tgz",
      "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw=="
    },
    "errno": {
      "version": "0.1.8",
      "resolved": "https://registry.npmmirror.com/errno/-/errno-0.1.8.tgz",
      "integrity": "sha512-dJ6oBr5SQ1VSd9qkk7ByRgb/1SH4JZjCHSW/mr63/QcXO9zLVxvJ6Oy13nio03rxpSnVDDjFor75SjVeZWPW/A==",
      "dev": true,
      "optional": true,
      "requires": {
        "prr": "~1.0.1"
      }
    },
    "esbuild": {
      "version": "0.21.5",
      "resolved": "https://registry.npmmirror.com/esbuild/-/esbuild-0.21.5.tgz",
      "integrity": "sha512-mg3OPMV4hXywwpoDxu3Qda5xCKQi+vCTZq8S9J/EpkhB2HzKXq4SNFZE3+NK93JYxc8VMSep+lOUSC/RVKaBqw==",
      "dev": true,
      "requires": {
        "@esbuild/aix-ppc64": "0.21.5",
        "@esbuild/android-arm": "0.21.5",
        "@esbuild/android-arm64": "0.21.5",
        "@esbuild/android-x64": "0.21.5",
        "@esbuild/darwin-arm64": "0.21.5",
        "@esbuild/darwin-x64": "0.21.5",
        "@esbuild/freebsd-arm64": "0.21.5",
        "@esbuild/freebsd-x64": "0.21.5",
        "@esbuild/linux-arm": "0.21.5",
        "@esbuild/linux-arm64": "0.21.5",
        "@esbuild/linux-ia32": "0.21.5",
        "@esbuild/linux-loong64": "0.21.5",
        "@esbuild/linux-mips64el": "0.21.5",
        "@esbuild/linux-ppc64": "0.21.5",
        "@esbuild/linux-riscv64": "0.21.5",
        "@esbuild/linux-s390x": "0.21.5",
        "@esbuild/linux-x64": "0.21.5",
        "@esbuild/netbsd-x64": "0.21.5",
        "@esbuild/openbsd-x64": "0.21.5",
        "@esbuild/sunos-x64": "0.21.5",
        "@esbuild/win32-arm64": "0.21.5",
        "@esbuild/win32-ia32": "0.21.5",
        "@esbuild/win32-x64": "0.21.5"
      }
    },
    "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=="
    },
    "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=="
    },
    "fsevents": {
      "version": "2.3.3",
      "resolved": "https://registry.npmmirror.com/fsevents/-/fsevents-2.3.3.tgz",
      "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==",
      "dev": true,
      "optional": true
    },
    "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,
      "optional": true
    },
    "iconv-lite": {
      "version": "0.6.3",
      "resolved": "https://registry.npmmirror.com/iconv-lite/-/iconv-lite-0.6.3.tgz",
      "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==",
      "dev": true,
      "optional": true,
      "requires": {
        "safer-buffer": ">= 2.1.2 < 3.0.0"
      }
    },
    "image-size": {
      "version": "0.5.5",
      "resolved": "https://registry.npmmirror.com/image-size/-/image-size-0.5.5.tgz",
      "integrity": "sha512-6TDAlDPZxUFCv+fuOkIoXT/V/f3Qbq8e37p+YOiYrUv3v9cc3/6x78VdfPgFVaB9dZYeLUfKgHRebpkm/oP2VQ==",
      "dev": true,
      "optional": true
    },
    "is-what": {
      "version": "3.14.1",
      "resolved": "https://registry.npmmirror.com/is-what/-/is-what-3.14.1.tgz",
      "integrity": "sha512-sNxgpk9793nzSs7bA6JQJGeIuRBQhAaNGG77kzYQgMkrID+lS6SlK07K5LaptscDlSaIgH+GPFzf+d75FVxozA==",
      "dev": true
    },
    "less": {
      "version": "4.2.2",
      "resolved": "https://registry.npmmirror.com/less/-/less-4.2.2.tgz",
      "integrity": "sha512-tkuLHQlvWUTeQ3doAqnHbNn8T6WX1KA8yvbKG9x4VtKtIjHsVKQZCH11zRgAfbDAXC2UNIg/K9BYAAcEzUIrNg==",
      "dev": true,
      "requires": {
        "copy-anything": "^2.0.1",
        "errno": "^0.1.1",
        "graceful-fs": "^4.1.2",
        "image-size": "~0.5.0",
        "make-dir": "^2.1.0",
        "mime": "^1.4.1",
        "needle": "^3.1.0",
        "parse-node-version": "^1.0.1",
        "source-map": "~0.6.0",
        "tslib": "^2.3.0"
      }
    },
    "less-loader": {
      "version": "12.2.0",
      "resolved": "https://registry.npmmirror.com/less-loader/-/less-loader-12.2.0.tgz",
      "integrity": "sha512-MYUxjSQSBUQmowc0l5nPieOYwMzGPUaTzB6inNW/bdPEG9zOL3eAAD1Qw5ZxSPk7we5dMojHwNODYMV1hq4EVg==",
      "dev": true,
      "requires": {}
    },
    "lodash": {
      "version": "4.17.21",
      "resolved": "https://registry.npmmirror.com/lodash/-/lodash-4.17.21.tgz",
      "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg=="
    },
    "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=="
    },
    "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==",
      "requires": {}
    },
    "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==",
      "requires": {
        "@jridgewell/sourcemap-codec": "^1.5.0"
      }
    },
    "make-dir": {
      "version": "2.1.0",
      "resolved": "https://registry.npmmirror.com/make-dir/-/make-dir-2.1.0.tgz",
      "integrity": "sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA==",
      "dev": true,
      "optional": true,
      "requires": {
        "pify": "^4.0.1",
        "semver": "^5.6.0"
      }
    },
    "memoize-one": {
      "version": "6.0.0",
      "resolved": "https://registry.npmmirror.com/memoize-one/-/memoize-one-6.0.0.tgz",
      "integrity": "sha512-rkpe71W0N0c0Xz6QD0eJETuWAJGnJ9afsl1srmwPrI+yBCkge5EycXXbYRyvL29zZVUWQCY7InPRCv3GDXuZNw=="
    },
    "mime": {
      "version": "1.6.0",
      "resolved": "https://registry.npmmirror.com/mime/-/mime-1.6.0.tgz",
      "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==",
      "dev": true,
      "optional": true
    },
    "nanoid": {
      "version": "3.3.8",
      "resolved": "https://registry.npmmirror.com/nanoid/-/nanoid-3.3.8.tgz",
      "integrity": "sha512-WNLf5Sd8oZxOm+TzppcYk8gVOgP+l58xNy58D0nbUnOxOWRWvlcCV4kUF7ltmI6PsrLl/BgKEyS4mqsGChFN0w=="
    },
    "needle": {
      "version": "3.3.1",
      "resolved": "https://registry.npmmirror.com/needle/-/needle-3.3.1.tgz",
      "integrity": "sha512-6k0YULvhpw+RoLNiQCRKOl09Rv1dPLr8hHnVjHqdolKwDrdNyk+Hmrthi4lIGPPz3r39dLx0hsF5s40sZ3Us4Q==",
      "dev": true,
      "optional": true,
      "requires": {
        "iconv-lite": "^0.6.3",
        "sax": "^1.2.4"
      }
    },
    "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=="
    },
    "parse-node-version": {
      "version": "1.0.1",
      "resolved": "https://registry.npmmirror.com/parse-node-version/-/parse-node-version-1.0.1.tgz",
      "integrity": "sha512-3YHlOa/JgH6Mnpr05jP9eDG254US9ek25LyIxZlDItp2iJtwyaXQb57lBYLdT3MowkUFYEV2XXNAYIPlESvJlA==",
      "dev": true
    },
    "picocolors": {
      "version": "1.1.1",
      "resolved": "https://registry.npmmirror.com/picocolors/-/picocolors-1.1.1.tgz",
      "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA=="
    },
    "pify": {
      "version": "4.0.1",
      "resolved": "https://registry.npmmirror.com/pify/-/pify-4.0.1.tgz",
      "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==",
      "dev": true,
      "optional": true
    },
    "postcss": {
      "version": "8.5.3",
      "resolved": "https://registry.npmmirror.com/postcss/-/postcss-8.5.3.tgz",
      "integrity": "sha512-dle9A3yYxlBSrt8Fu+IpjGT8SY8hN0mlaA6GY8t0P5PjIOZemULz/E2Bnm/2dcUOena75OTNkHI76uZBNUUq3A==",
      "requires": {
        "nanoid": "^3.3.8",
        "picocolors": "^1.1.1",
        "source-map-js": "^1.2.1"
      }
    },
    "prr": {
      "version": "1.0.1",
      "resolved": "https://registry.npmmirror.com/prr/-/prr-1.0.1.tgz",
      "integrity": "sha512-yPw4Sng1gWghHQWj0B3ZggWUm4qVbPwPFcRG8KyxiU7J2OHFSoEHKS+EZ3fv5l1t9CyCiop6l/ZYeWbrgoQejw==",
      "dev": true,
      "optional": true
    },
    "rollup": {
      "version": "4.34.8",
      "resolved": "https://registry.npmmirror.com/rollup/-/rollup-4.34.8.tgz",
      "integrity": "sha512-489gTVMzAYdiZHFVA/ig/iYFllCcWFHMvUHI1rpFmkoUtRlQxqh6/yiNqnYibjMZ2b/+FUQwldG+aLsEt6bglQ==",
      "dev": true,
      "requires": {
        "@rollup/rollup-android-arm-eabi": "4.34.8",
        "@rollup/rollup-android-arm64": "4.34.8",
        "@rollup/rollup-darwin-arm64": "4.34.8",
        "@rollup/rollup-darwin-x64": "4.34.8",
        "@rollup/rollup-freebsd-arm64": "4.34.8",
        "@rollup/rollup-freebsd-x64": "4.34.8",
        "@rollup/rollup-linux-arm-gnueabihf": "4.34.8",
        "@rollup/rollup-linux-arm-musleabihf": "4.34.8",
        "@rollup/rollup-linux-arm64-gnu": "4.34.8",
        "@rollup/rollup-linux-arm64-musl": "4.34.8",
        "@rollup/rollup-linux-loongarch64-gnu": "4.34.8",
        "@rollup/rollup-linux-powerpc64le-gnu": "4.34.8",
        "@rollup/rollup-linux-riscv64-gnu": "4.34.8",
        "@rollup/rollup-linux-s390x-gnu": "4.34.8",
        "@rollup/rollup-linux-x64-gnu": "4.34.8",
        "@rollup/rollup-linux-x64-musl": "4.34.8",
        "@rollup/rollup-win32-arm64-msvc": "4.34.8",
        "@rollup/rollup-win32-ia32-msvc": "4.34.8",
        "@rollup/rollup-win32-x64-msvc": "4.34.8",
        "@types/estree": "1.0.6",
        "fsevents": "~2.3.2"
      }
    },
    "safer-buffer": {
      "version": "2.1.2",
      "resolved": "https://registry.npmmirror.com/safer-buffer/-/safer-buffer-2.1.2.tgz",
      "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==",
      "dev": true,
      "optional": true
    },
    "sax": {
      "version": "1.4.1",
      "resolved": "https://registry.npmmirror.com/sax/-/sax-1.4.1.tgz",
      "integrity": "sha512-+aWOz7yVScEGoKNd4PA10LZ8sk0A/z5+nXQG5giUO5rprX9jgYsTdov9qCchZiPIZezbZH+jRut8nPodFAX4Jg==",
      "dev": true,
      "optional": true
    },
    "semver": {
      "version": "5.7.2",
      "resolved": "https://registry.npmmirror.com/semver/-/semver-5.7.2.tgz",
      "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==",
      "dev": true,
      "optional": true
    },
    "source-map": {
      "version": "0.6.1",
      "resolved": "https://registry.npmmirror.com/source-map/-/source-map-0.6.1.tgz",
      "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
      "dev": true,
      "optional": true
    },
    "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=="
    },
    "tslib": {
      "version": "2.8.1",
      "resolved": "https://registry.npmmirror.com/tslib/-/tslib-2.8.1.tgz",
      "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==",
      "dev": true
    },
    "vite": {
      "version": "5.4.14",
      "resolved": "https://registry.npmmirror.com/vite/-/vite-5.4.14.tgz",
      "integrity": "sha512-EK5cY7Q1D8JNhSaPKVK4pwBFvaTmZxEnoKXLG/U9gmdDcihQGNzFlgIvaxezFR4glP1LsuiedwMBqCXH3wZccA==",
      "dev": true,
      "requires": {
        "esbuild": "^0.21.3",
        "fsevents": "~2.3.3",
        "postcss": "^8.4.43",
        "rollup": "^4.20.0"
      }
    },
    "vue": {
      "version": "3.5.13",
      "resolved": "https://registry.npmmirror.com/vue/-/vue-3.5.13.tgz",
      "integrity": "sha512-wmeiSMxkZCSc+PM2w2VRsOYAZC8GdipNFRTsLSfodVqI9mbejKeXEGr8SckuLnrQPGe3oJN5c3K0vpoU9q/wCQ==",
      "requires": {
        "@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"
      }
    },
    "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==",
      "requires": {
        "@vue/devtools-api": "^6.6.4"
      }
    }
  }
}
package.json
New file
@@ -0,0 +1,27 @@
{
  "name": "model",
  "private": true,
  "version": "0.0.0",
  "type": "module",
  "main": "index.js",
  "license": "MIT",
  "scripts": {
    "dev": "vite",
    "build": "vite build",
    "preview": "vite preview"
  },
  "dependencies": {
    "@element-plus/icons-vue": "^2.3.1",
    "element-plus": "^2.5.6",
    "vue": "^3.4.21",
    "vue-router": "^4.3.0",
    "axios": "^1.6.2",
    "spark-md5": "^3.0.2"
  },
  "devDependencies": {
    "@vitejs/plugin-vue": "^5.0.4",
    "less": "^4.2.2",
    "less-loader": "^12.2.0",
    "vite": "^5.1.6"
  }
}
public/vite.svg
New file
@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" class="iconify iconify--logos" width="31.88" height="32" preserveAspectRatio="xMidYMid meet" viewBox="0 0 256 257"><defs><linearGradient id="IconifyId1813088fe1fbc01fb466" x1="-.828%" x2="57.636%" y1="7.652%" y2="78.411%"><stop offset="0%" stop-color="#41D1FF"></stop><stop offset="100%" stop-color="#BD34FE"></stop></linearGradient><linearGradient id="IconifyId1813088fe1fbc01fb467" x1="43.376%" x2="50.316%" y1="2.242%" y2="89.03%"><stop offset="0%" stop-color="#FFEA83"></stop><stop offset="8.333%" stop-color="#FFDD35"></stop><stop offset="100%" stop-color="#FFA800"></stop></linearGradient></defs><path fill="url(#IconifyId1813088fe1fbc01fb466)" d="M255.153 37.938L134.897 252.976c-2.483 4.44-8.862 4.466-11.382.048L.875 37.958c-2.746-4.814 1.371-10.646 6.827-9.67l120.385 21.517a6.537 6.537 0 0 0 2.322-.004l117.867-21.483c5.438-.991 9.574 4.796 6.877 9.62Z"></path><path fill="url(#IconifyId1813088fe1fbc01fb467)" d="M185.432.063L96.44 17.501a3.268 3.268 0 0 0-2.634 3.014l-5.474 92.456a3.268 3.268 0 0 0 3.997 3.378l24.777-5.718c2.318-.535 4.413 1.507 3.936 3.838l-7.361 36.047c-.495 2.426 1.782 4.5 4.151 3.78l15.304-4.649c2.372-.72 4.652 1.36 4.15 3.788l-11.698 56.621c-.732 3.542 3.979 5.473 5.943 2.437l1.313-2.028l72.516-144.72c1.215-2.423-.88-5.186-3.54-4.672l-25.505 4.922c-2.396.462-4.435-1.77-3.759-4.114l16.646-57.705c.677-2.35-1.37-4.583-3.769-4.113Z"></path></svg>
src/App.vue
New file
@@ -0,0 +1,45 @@
<script setup lang="ts">
// import { RouterView } from "vue-router";
import Header from './layout/Header.vue';
import TreeMenu from './components/TreeMenu.vue';
</script>
<template>
  <div class="common-layout">
    <el-container>
      <el-header height="60px">
        <Header/>
      </el-header>
      <el-container>
        <el-aside width="240px">
          <TreeMenu />
        </el-aside>
        <el-main>
          <RouterView />
        </el-main>
      </el-container>
    </el-container>
  </div>
</template>
<style lang="less">
.common-layout {
  height: 100vh;
  .el-container {
    height: 100%;
  }
  .el-header {
    background-color: #fff;
    color: #333;
    line-height: 60px;
    border-bottom: 1px solid #eee;
  }
  .el-aside {
    background-color: #fff;
    border-right: 1px solid #eee;
  }
  .el-main {
    background-color: #f5f7fa;
  }
}
</style>
src/assets/js/canvas2image.js
New file
@@ -0,0 +1,266 @@
/**
 * covert canvas to image
 * and save the image file
 */
var Canvas2Image = function () {
    // check if support sth.
    var $support = function () {
        var canvas = document.createElement('canvas'),
            ctx = canvas.getContext('2d');
        return {
            canvas: !!ctx,
            imageData: !!ctx.getImageData,
            dataURL: !!canvas.toDataURL,
            btoa: !!window.btoa
        };
    }();
    var downloadMime = 'image/octet-stream';
    function scaleCanvas (canvas, width, height) {
        var w = canvas.width,
            h = canvas.height;
        if (width == undefined) {
            width = w;
        }
        if (height == undefined) {
            height = h;
        }
        var retCanvas = document.createElement('canvas');
        var retCtx = retCanvas.getContext('2d');
        retCanvas.width = width;
        retCanvas.height = height;
        retCtx.drawImage(canvas, 0, 0, w, h, 0, 0, width, height);
        return retCanvas;
    }
    function getDataURL (canvas, type, width, height) {
        canvas = scaleCanvas(canvas, width, height);
        return canvas.toDataURL(type);
    }
    function saveFile (strData) {
        document.location.href = strData;
    }
    function genImage(strData) {
        var img = document.createElement('img');
        img.src = strData;
        return img;
    }
    function fixType (type) {
        type = type.toLowerCase().replace(/jpg/i, 'jpeg');
        var r = type.match(/png|jpeg|bmp|gif/)[0];
        return 'image/' + r;
    }
    function encodeData (data) {
        if (!window.btoa) { throw 'btoa undefined' }
        var str = '';
        if (typeof data == 'string') {
            str = data;
        } else {
            for (var i = 0; i < data.length; i ++) {
                str += String.fromCharCode(data[i]);
            }
        }
        return btoa(str);
    }
    function getImageData (canvas) {
        var w = canvas.width,
            h = canvas.height;
        return canvas.getContext('2d').getImageData(0, 0, w, h);
    }
    function makeURI (strData, type) {
        return 'data:' + type + ';base64,' + strData;
    }
    /**
     * create bitmap image
     * 按照规则生成图片响应头和响应体
     */
    var genBitmapImage = function (oData) {
        //
        // BITMAPFILEHEADER: http://msdn.microsoft.com/en-us/library/windows/desktop/dd183374(v=vs.85).aspx
        // BITMAPINFOHEADER: http://msdn.microsoft.com/en-us/library/dd183376.aspx
        //
        var biWidth  = oData.width;
        var biHeight    = oData.height;
        var biSizeImage = biWidth * biHeight * 3;
        var bfSize  = biSizeImage + 54; // total header size = 54 bytes
        //
        //  typedef struct tagBITMAPFILEHEADER {
        //      WORD bfType;
        //      DWORD bfSize;
        //      WORD bfReserved1;
        //      WORD bfReserved2;
        //      DWORD bfOffBits;
        //  } BITMAPFILEHEADER;
        //
        var BITMAPFILEHEADER = [
            // WORD bfType -- The file type signature; must be "BM"
            0x42, 0x4D,
            // DWORD bfSize -- The size, in bytes, of the bitmap file
            bfSize & 0xff, bfSize >> 8 & 0xff, bfSize >> 16 & 0xff, bfSize >> 24 & 0xff,
            // WORD bfReserved1 -- Reserved; must be zero
            0, 0,
            // WORD bfReserved2 -- Reserved; must be zero
            0, 0,
            // DWORD bfOffBits -- The offset, in bytes, from the beginning of the BITMAPFILEHEADER structure to the bitmap bits.
            54, 0, 0, 0
        ];
        //
        //  typedef struct tagBITMAPINFOHEADER {
        //      DWORD biSize;
        //      LONG  biWidth;
        //      LONG  biHeight;
        //      WORD  biPlanes;
        //      WORD  biBitCount;
        //      DWORD biCompression;
        //      DWORD biSizeImage;
        //      LONG  biXPelsPerMeter;
        //      LONG  biYPelsPerMeter;
        //      DWORD biClrUsed;
        //      DWORD biClrImportant;
        //  } BITMAPINFOHEADER, *PBITMAPINFOHEADER;
        //
        var BITMAPINFOHEADER = [
            // DWORD biSize -- The number of bytes required by the structure
            40, 0, 0, 0,
            // LONG biWidth -- The width of the bitmap, in pixels
            biWidth & 0xff, biWidth >> 8 & 0xff, biWidth >> 16 & 0xff, biWidth >> 24 & 0xff,
            // LONG biHeight -- The height of the bitmap, in pixels
            biHeight & 0xff, biHeight >> 8  & 0xff, biHeight >> 16 & 0xff, biHeight >> 24 & 0xff,
            // WORD biPlanes -- The number of planes for the target device. This value must be set to 1
            1, 0,
            // WORD biBitCount -- The number of bits-per-pixel, 24 bits-per-pixel -- the bitmap
            // has a maximum of 2^24 colors (16777216, Truecolor)
            24, 0,
            // DWORD biCompression -- The type of compression, BI_RGB (code 0) -- uncompressed
            0, 0, 0, 0,
            // DWORD biSizeImage -- The size, in bytes, of the image. This may be set to zero for BI_RGB bitmaps
            biSizeImage & 0xff, biSizeImage >> 8 & 0xff, biSizeImage >> 16 & 0xff, biSizeImage >> 24 & 0xff,
            // LONG biXPelsPerMeter, unused
            0,0,0,0,
            // LONG biYPelsPerMeter, unused
            0,0,0,0,
            // DWORD biClrUsed, the number of color indexes of palette, unused
            0,0,0,0,
            // DWORD biClrImportant, unused
            0,0,0,0
        ];
        var iPadding = (4 - ((biWidth * 3) % 4)) % 4;
        var aImgData = oData.data;
        var strPixelData = '';
        var biWidth4 = biWidth<<2;
        var y = biHeight;
        var fromCharCode = String.fromCharCode;
        do {
            var iOffsetY = biWidth4*(y-1);
            var strPixelRow = '';
            for (var x = 0; x < biWidth; x++) {
                var iOffsetX = x<<2;
                strPixelRow += fromCharCode(aImgData[iOffsetY+iOffsetX+2]) +
                               fromCharCode(aImgData[iOffsetY+iOffsetX+1]) +
                               fromCharCode(aImgData[iOffsetY+iOffsetX]);
            }
            for (var c = 0; c < iPadding; c++) {
                strPixelRow += String.fromCharCode(0);
            }
            strPixelData += strPixelRow;
        } while (--y);
        var strEncoded = encodeData(BITMAPFILEHEADER.concat(BITMAPINFOHEADER)) + encodeData(strPixelData);
        return strEncoded;
    };
    /**
     * saveAsImage
     * @param canvasElement
     * @param {String} image type
     * @param {Number} [optional] png width
     * @param {Number} [optional] png height
     */
    var saveAsImage = function (canvas, width, height, type) {
        if ($support.canvas && $support.dataURL) {
            if (typeof canvas == "string") { canvas = document.getElementById(canvas); }
            if (type == undefined) { type = 'png'; }
            type = fixType(type);
            if (/bmp/.test(type)) {
                var data = getImageData(scaleCanvas(canvas, width, height));
                var strData = genBitmapImage(data);
                saveFile(makeURI(strData, downloadMime));
            } else {
                var strData = getDataURL(canvas, type, width, height);
                saveFile(strData.replace(type, downloadMime));
            }
        }
    };
    var convertToImage = function (canvas, width, height, type) {
        if ($support.canvas && $support.dataURL) {
            if (typeof canvas == "string") { canvas = document.getElementById(canvas); }
            if (type == undefined) { type = 'png'; }
            type = fixType(type);
            if (/bmp/.test(type)) {
                var data = getImageData(scaleCanvas(canvas, width, height));
                var strData = genBitmapImage(data);
                return genImage(makeURI(strData, 'image/bmp'));
            } else {
                var strData = getDataURL(canvas, type, width, height);
                return genImage(strData);
            }
        }
    };
    return {
        saveAsImage: saveAsImage,
        saveAsPNG: function (canvas, width, height) {
            return saveAsImage(canvas, width, height, 'png');
        },
        saveAsJPEG: function (canvas, width, height) {
            return saveAsImage(canvas, width, height, 'jpeg');
        },
        saveAsGIF: function (canvas, width, height) {
            return saveAsImage(canvas, width, height, 'gif');
        },
        saveAsBMP: function (canvas, width, height) {
            return saveAsImage(canvas, width, height, 'bmp');
        },
        convertToImage: convertToImage,
        convertToPNG: function (canvas, width, height) {
            return convertToImage(canvas, width, height, 'png');
        },
        convertToJPEG: function (canvas, width, height) {
            return convertToImage(canvas, width, height, 'jpeg');
        },
        convertToGIF: function (canvas, width, height) {
            return convertToImage(canvas, width, height, 'gif');
        },
        convertToBMP: function (canvas, width, height) {
            return convertToImage(canvas, width, height, 'bmp');
        }
    };
}();
export default Canvas2Image;
src/assets/js/config.js
New file
@@ -0,0 +1,31 @@
// export const requestCtx = "http://182.92.203.7:3001"; // 请求地址
// export const appId = 27;
export const requestCtx = 'https://jsek.bnuic.com' // 请求地址
export const appId = 3
export const requestTimeOut = 300000 // 请求超时时间
export const tokenKey = 'jsek-token'
export const userInfoKey = 'jesk-userInfo' // 用户信息key
export const appRefCode = 'jingshieke'
export const goodsStore = `defaultGoodsStore${appId}` // 默认商品库(书城)
export const publicStore = `defaultPublicStore${appId}` // 默认资源开放仓储
export const publicRepository = `defaultPublicRepository${appId}` // 默认资源开放库
export const digitalCourses = 'jsek_digitalCourses' //数字课程
export const digitalTextbooks = 'jsek_digitalTextbooks' //数字教材
export const seminar = 'jsek_seminar' //专题研讨
const config = {
  requestCtx,
  requestTimeOut,
  tokenKey,
  userInfoKey,
  appRefCode,
  goodsStore,
  digitalCourses,
  digitalTextbooks,
  seminar,
  appId
}
export default config
src/assets/js/iframe.js
New file
@@ -0,0 +1,32 @@
let isSelect = false;
let move = false;
document.addEventListener('mousedown', () => {
    isSelect = true;
});
document.addEventListener('mousemove', () => {
    if (isSelect) {
        move = true;
    }
});
document.addEventListener('mouseup', (e) => {
    isSelect = false;
    if (move) {
        const selection = window.getSelection();
        if (selection && selection.toString().length != 0) {
            parent.window.selectChange(e)
        }
    }
    move = false;
    e.preventDefault();
});
parent.window.document.getElementsByClassName("epub-container")[0].addEventListener("scroll", function (e) {
    parent.window.scroll(e); // 调用处理函数并传入参数
})
src/assets/js/middleGround/WebMiddleGroundApi.js
New file
@@ -0,0 +1,24 @@
// 取消接口调用能力;
// 队列的必要性??
import resource from "./api/resource.js";
import store from "./api/store.js";
import identity from "./api/identity.js";
import ugc from "./api/ugc.js";
import app from "./api/app.js";
import file from "./api/file.js";
import job from "./api/job.js";
import edu from "./api/edu.js";
const WebMiddleGroundApi = {
  resource,
  store,
  identity,
  ugc,
  app,
  file,
  job,
  edu
};
export default WebMiddleGroundApi;
src/assets/js/middleGround/api/app.js
New file
@@ -0,0 +1,82 @@
import request from '@/plugin/axios/index.ts'
const appApi = {
  // 获取用户消息列表
  getAppMessageList(data) {
    return request({
      url: '/app/api/ApiGetAppMessageList',
      method: 'post',
      data
    })
  },
  // 获取用户消息详情
  getMessage(data) {
    return request({
      url: '/app/api/ApiGetMessage',
      method: 'post',
      data
    })
  },
  //获取凭证
  getTicketResult(data) {
    return request({
      url: '/app/api/ApiGetTicketResult',
      method: 'post',
      data
    })
  },
  //使用凭证
  useTicket(data) {
    return request({
      url: '/app/api/ApiUseTicket',
      method: 'post',
      data
    })
  },
  // 获取CmsItem按照Event统计
  getEventRankList(data) {
    return request({
      url: '/app/api/ApiGetEventRankList',
      method: 'post',
      data
    })
  },
  // 获取学习时长按照Event统计
  getStaticsSum(data) {
    return request({
      url: '/app/api/ApiGetUserStaticsSum',
      method: 'post',
      data
    })
  },
  // 新建用户行为
  creatUserBehavior(data) {
    return request({
      url: '/app/api/NewUserBehavior',
      method: 'post',
      data
    })
  },
  // 获取用户行为记录
  getUserBehaviorList(data) {
    return request({
      url: '/app/api/GetUserBehaviorList',
      method: 'post',
      data
    })
  },
  //获取小程序二维码
  getWeChatAppQrCode(data) {
    return request({
      url: '/app/api/GetWeChatAppQrCode',
      method: 'post',
      data
    })
  }
}
export default appApi
src/assets/js/middleGround/api/edu.js
New file
@@ -0,0 +1,319 @@
import request from '@/plugin/axios/index.ts'
import { handleQueryResourceListData } from '../tool'
const eduApi = {
  // 获取商品下的组卷策略
  getQuizConfigListByProduct(data) {
    return request({
      url: '/edu/api/ApiGetQuizConfigListByProduct',
      method: 'post',
      data
    })
  },
  // 获取组卷结果
  getEduQuizConfigResult(data) {
    return request({
      url: '/edu/api/ApiGetEduQuizConfigResult',
      method: 'post',
      data
    })
  },
  //申请课程
  applyNewCourse(data) {
    return request({
      url: '/edu/api/ApiApplyNewCourse',
      method: 'post',
      data
    })
  },
  //更新课程信息
  updateCourse(data) {
    return request({
      url: '/edu/api/ApiUpdateCourse',
      method: 'post',
      data
    })
  },
  //更新课程申请信息
  updateCourseApply(data) {
    return request({
      url: '/edu/api/ApiUpdateCourseApply',
      method: 'post',
      data
    })
  },
  //获取我的课程
  getAppCourseList(data) {
    return request({
      url: '/edu/api/ApiGetAppCourseList',
      method: 'post',
      data
    })
  },
  //获取已申请的课程详情
  getCourseById(data) {
    return request({
      url: '/edu/api/ApiGetCourseById',
      method: 'post',
      data
    })
  },
  //获取创建课程中的班级列表
  getCourseClassList(data) {
    return request({
      url: '/edu/api/ApiGetCourseClassList',
      method: 'post',
      data
    })
  },
  //创建班级信息
  newCourseClass(data) {
    return request({
      url: '/edu/api/ApiNewCourseClass',
      method: 'post',
      data
    })
  },
  //删除班级信息
  delCourseClass(data) {
    return request({
      url: '/edu/api/ApiDelCourseClass',
      method: 'post',
      data
    })
  },
  // 更新班级信息
  updateCourseClass(data) {
    return request({
      url: '/edu/api/ApiUpdateCourseClass',
      method: 'post',
      data
    })
  },
  // 获取班级详情
  getCourseClass(data) {
    return request({
      url: '/edu/api/ApiGetCourseClass',
      method: 'post',
      data
    })
  },
  // 获取topic信息
  getClassTopic(data) {
    return request({
      url: '/edu/api/ApiGetClassTopic',
      method: 'post',
      data
    })
  },
  //创建课程订单
  createCourseOrder(data) {
    return request({
      url: '/store/api/CreateCourseOrder',
      method: 'post',
      data
    })
  },
  // 免费领取课程
  makeFreeOrderPay(data) {
    return request({
      url: '/store/api/MakeFreeOrderPay',
      method: 'post',
      data
    })
  },
  // 获取排名结果
  getRankingList(data) {
    return request({
      url: '/edu/api/ApiGetRankingList',
      method: 'post',
      data
    })
  },
  //获取个人排名
  getRanking(data) {
    return request({
      url: '/edu/api/ApiGetTopRanking',
      method: 'post',
      data
    })
  },
  // 新建排名记录
  newRanking(data) {
    return request({
      url: '/edu/api/ApiNewRanking',
      method: 'post',
      data
    })
  },
  // 删除组卷规则
  delQuizConfig(data) {
    return request({
      url: '/edu/admin/DelQuizConfig',
      method: 'post',
      data
    })
  },
  // 更新组卷规则
  updateQuizConfig(data) {
    return request({
      url: '/edu/admin/UpdateQuizConfig',
      method: 'post',
      data
    })
  },
  // 根据ID获取组卷配置
  getQuizConfig(data) {
    return request({
      url: '/edu/admin/GetQuizConfig',
      method: 'post',
      data
    })
  },
  // 为班级新建任务
  newTask(data) {
    return request({
      url: '/edu/api/ApiNewTask',
      method: 'post',
      data
    })
  },
  // 更新任务
  updateTask(data) {
    return request({
      url: '/edu/api/ApiUpdateTask',
      method: 'post',
      data
    })
  },
  // 获取班级任务列表
  getTaskList(data) {
    return request({
      url: '/edu/api/ApiGetTaskList',
      method: 'post',
      data
    })
  },
  // 删除班级任务列表
  delTask(data) {
    return request({
      url: '/edu/api/ApiDelTask',
      method: 'post',
      data
    })
  },
  // 为任务新建资源
  newTaskCmsItem(data) {
    return request({
      url: '/edu/api/ApiNewTaskCmsItem',
      method: 'post',
      data
    })
  },
  // 获取任务下的资源列表
  getTaskCmsItem(data) {
    return request({
      url: '/edu/api/ApiGetTaskCmsItem',
      method: 'post',
      data
    })
  },
  // 删除任务下的资源列表
  removeTaskCmsItemList(data) {
    return request({
      url: '/edu/api/ApiRemoveTaskCmsItemList',
      method: 'post',
      data
    })
  },
  // 为任务添加资源
  addTaskCmsItemList(data) {
    return request({
      url: '/edu/api/ApiAddTaskCmsItemList',
      method: 'post',
      data
    })
  },
  // 获取任务提交列表
  getTaskSubmitList(data) {
    return request({
      url: '/edu/api/ApiGetTaskSubmitList',
      method: 'post',
      data
    })
  },
  // 获取未提交任务列表
  getUnSubmitList(data) {
    return request({
      url: '/edu/api/ApiGetUnSubmitList',
      method: 'post',
      data
    })
  },
  // 为任务新建提交
  newTaskSubmit(data) {
    return request({
      url: '/edu/api/ApiNewTaskSubmit',
      method: 'post',
      data
    })
  },
  // 更新任务提交
  updateTaskSubmit(data) {
    return request({
      url: '/edu/api/ApiUpdateTaskSubmit',
      method: 'post',
      data
    })
  },
  // 获取任务提交统计
  getTaskStatistics(data) {
    return request({
      url: '/edu/api/ApiGetTaskStatistics',
      method: 'post',
      data
    })
  },
  // 获取用户提交统计列表
  getUserTaskList(data) {
    return request({
      url: '/edu/api/ApiGetUserTaskList',
      method: 'post',
      data
    })
  }
}
export default eduApi
src/assets/js/middleGround/api/file.js
New file
@@ -0,0 +1,94 @@
import request from "@/plugin/axios/index.ts";
const fileApi = {
  // 获取pdf总页数
  getPdfTotalPage(data) {
    return request({
      url: "/file/GetPdfTotalPage",
      method: "post",
      data
    });
  },
  // 获取pdf、word、ppt等转图片预览
  getPdfInfo(data) {
    return request({
      url: "/file/GetPdfInfo",
      method: "post",
      data
    });
  },
  //获取pdf目录
  GetPdfToc(data) {
    return request({
      url: "/file/GetPdfToc",
      method: "post",
      data
    });
  },
  //获取文件
  getPdfPageImage(params) {
    return request({
      url: '/file/GetPdfPageImage',
      method: 'get',
      responseType: 'blob',
      params
    });
  },
  //上传文件
  upload(data) {
    return request({
      url: "/file/api/ApiUpload",
      method: "post",
      data
    });
  },
  // 获取阿里云加速地址
  getAliVod(data) {
    return request({
      url: "/file/GetAliVod",
      method: "post",
      data,
    });
  },
  downloadForAuthorize(params) {
    return request({
      url: '/file/api/ApiDownloadForAuthorize',
      method: 'GET',
      responseType: 'blob',
      params
    });
  },
  // 批量下载
  downloadFiles(data) {
    return request({
      url: '/file/api/ApiDownloadFiles',
      method: 'post',
      responseType: 'blob',
      data
    });
  },
  // 批量下载get
  getDownloadFiles (params) {
    return request({
      url: '/file/api/ApiGetDownloadFiles',
      method: 'GET',
      responseType: 'blob',
      headers:{
        'md5s':params
      }
    });
  },
  // 发送下载邮件
  sendFileEmail (data) {
    return request({
      url:'/file/api/ApiSendFileWithEmail',
      method:'post',
      data
    })
  }
}
export default fileApi;
src/assets/js/middleGround/api/identity.js
New file
@@ -0,0 +1,225 @@
import request from '@/plugin/axios/index.ts'
const identityApi = {
  // 获取图形验证码
  getImgCode() {
    return request({
      url: '/identity/NewCaptcha',
      method: 'post'
    })
  },
  // 验证图形验证码
  verificationImgCode(data) {
    return request({
      url: '/identity/ValidCaptcha',
      method: 'post',
      data
    })
  },
  // 获取短信验证码
  getPhoneCode(data) {
    return request({
      url: '/identity/NewSms',
      method: 'post',
      data
    })
  },
  // 验证短信验证码
  verificationPhoneCode(data) {
    return request({
      url: '/identity/api/ApiValidMobilePhone',
      method: 'post',
      data
    })
  },
  // 通过手机号注册用户
  registerAppUserWithPhone(data) {
    return request({
      url: '/identity/api/RegisterAppUserWithPhone',
      method: 'post',
      data
    })
  },
  // 账号密码登录
  loginByPassword(data) {
    return request({
      url: '/identity/api/LoginByPassword',
      method: 'post',
      data
    })
  },
  // 短信验证码登录
  loginByMobilePhone(data) {
    return request({
      url: '/identity/api/LoginByMobilePhone',
      method: 'post',
      data
    })
  },
  // 设置用户key
  setUserKey(data) {
    return request({
      url: '/identity/api/ApiAppUserSetKey',
      method: 'post',
      data
    })
  },
  // 获取用户key
  getUserKey(data) {
    return request({
      url: '/identity/api/ApiGetAppUserKey',
      method: 'post',
      data
    })
  },
  // 删除用户key
  delUserKey(data) {
    return request({
      url: '/identity/api/ApiDelAppUserKey',
      method: 'post',
      data
    })
  },
  // 获取去当前用户信息
  getCurrentAppUser() {
    return request({
      url: '/identity/api/GetCurrentAppUser',
      method: 'post'
    })
  },
  // 添加用户信息
  setAppUserInfo(data) {
    return request({
      url: '/identity/api/SetAppUserInfoRequest',
      method: 'post',
      data
    })
  },
  // 用户更换绑定手机号,如没有绑定手机则自动创建
  userSetPhoneNumber(data) {
    return request({
      url: '/identity/api/ApiUserSetPhoneNumber',
      method: 'post',
      data
    })
  },
  // 检测用户是否绑定微信
  checkBuildingWeChat(data) {
    return request({
      url: '/identity/api/ApiCheckBuildingWeChat',
      method: 'post',
      data
    })
  },
  // 通过手机号重置密码
  changePasswordByMobilePhone(data) {
    return request({
      url: '/identity/api/ChangePasswordByMobilePhone',
      method: 'post',
      data
    })
  },
  // 微信开放平台扫码登录
  loginByWeChatOpenCode(data) {
    return request({
      url: '/identity/api/LoginByWeChatOpenCode',
      method: 'post',
      data
    })
  },
  // 用户绑定微信号
  bindingWeChat(data) {
    return request({
      url: '/identity/api/ApiBindingWeChat',
      method: 'post',
      data
    })
  },
  // 设置登录的用户名和密码,用户名和密码至少6位
  setLoginNameAndPassword(data) {
    return request({
      url: '/identity/api/ApiUserSetLoginNameAndPassword',
      method: 'post',
      data
    })
  },
  // 获取邮箱验证码
  getEmailCode(data) {
    return request({
      url: '/identity/api/SendVerifyEMail',
      method: 'post',
      data
    })
  },
  // 用户绑定邮箱
  bindingEmail(data) {
    return request({
      url: '/identity/api/ApiBindEMail',
      method: 'post',
      data
    })
  },
  // 通过refcode加入班级/组
  joinGroupByRefCode(data) {
    return request({
      url: '/identity/api/ApiJoinGroupByRefCode',
      method: 'post',
      data
    })
  },
  // 获取加入组的列表信息
  joinedGroupByList(data) {
    return request({
      url: '/identity/api/ApiGetJoinedGroupByList',
      method: 'post',
      data
    })
  },
  // 获取组或班级成员
  getGroupUserList(data) {
    return request({
      url: '/identity/api/ApiGetGroupUserList',
      method: 'post',
      data
    })
  },
  // 更新组成员或班级成员状态
  updateAppUserGroupLink(data) {
    return request({
      url: '/identity/api/ApiUpdateAppUserGroupLink',
      method: 'post',
      data
    })
  },
  // 删除组成员或班级成员状态
  removeAppUserFromGroup(data) {
    return request({
      url: '/identity/api/ApiRemoveAppUserFromGroup',
      method: 'post',
      data
    })
  }
}
export default identityApi
src/assets/js/middleGround/api/job.js
New file
@@ -0,0 +1,34 @@
import request from "@/plugin/axios/index.ts";
import { tokenKey } from "@/assets/js/config";
import toolClass from "@/assets/js/toolClass";
const jobApi = {
  // 统计
  newJobWithNewView(data) {
    return request({
      url: "/job/api/NewJobWithNewView",
      method: "post",
      data
    });
  },
  newSession(data) {
    let token = toolClass.getCookie(tokenKey);
    return request({
      url: token ? "/job/api/AppUserNewSession" : "/job/api/NewSession",
      method: "post",
      data
    });
  },
  newJobWithApiNewEvent(data){
    return request({
      url: "/job/api/NewJobWithApiNewEvent",
      method: "post",
      data
    });
  }
};
export default jobApi;
src/assets/js/middleGround/api/resource.js
New file
@@ -0,0 +1,223 @@
import request from "@/plugin/axios/index.ts";
import { publicStore, publicRepository } from "@/assets/js/config";
import { tokenKey } from "@/assets/js/config";
import { handleQueryResourceListData } from "../tool";
import toolClass from "@/assets/js/toolClass";
const resourceApi = {
  /*
    **获取资源列表&详情**
    path: 数据路径
    storeInfo: 仓储
    repositoryInfo: 仓库
    queryType: 检索类型
    paging: 分页
    sort: 排序
    fields: 自定义字段
    itemId: 获取详情时的资源ID
  */
  getItem: ({
    path,
    storeInfo = publicStore,
    repositoryInfo = publicRepository,
    queryType,
    linkType,
    paging,
    sort,
    fields,
    itemId,
    itemIds,
    itemType,
    coverSize,
    itemIdArr,
    SysType,
    tourism_isHighQualityResources,
  }) => {
    if (!path) return Promise.reject("接口请求必要参数不能为空!");
    const query = {
      AccessControl: {
        Path: path,
        StoreRefCode: storeInfo + "",
        RepositoryRefCode: repositoryInfo + "",
        Type: queryType || "\\",
        LinkType: linkType || "",
      },
      PageQuery: {
        Start: paging?.start || "0",
        Size: paging?.size || "10",
      },
      SortQuery: sort ? [sort] : [{
        LinkOrder: "Desc"
      }],
      CreateDate: [],
      Description: [],
      Name: [],
      Icon: [],
      RefCode: [],
      Type: [],
      TypeId: [],
      State: [],
      Tag: [],
      LinkInfo: [],
      LinkFile: [],
      CmsItemType: [],
      ChildrenFolderCount: [],
      ChildrenCount: [],
      ...fields,
    };
    if (itemIdArr) query["Id"] = itemIdArr;
    if (SysType) query["SysType="] = [`${SysType}`];
    if (tourism_isHighQualityResources)
      query["tourism_isHighQualityResources="] = [
        `${tourism_isHighQualityResources}`,
      ];
    if (itemId) query["Id="] = [`${itemId}`];
    if (itemIds) query["Id="] = itemIds;
    if (itemType) query["Type="] = [`${itemType}`];
    const body = { query: JSON.stringify({ Query: [{ Q1: query }] }) };
    let token = localStorage.getItem(tokenKey);
    return request({
      url: token ? "/resource/api/ApiAppUserQuery" : "/resource/api/ApiQuery",
      method: "post",
      data: body,
    }).then((resp) => {
      if (resp.length > 0) {
        const data = resp[0];
        const datas = handleQueryResourceListData({
          datas: data.datas,
          fields,
          path,
          storeInfo,
          repositoryInfo,
          coverSize,
        });
        return { datas, total: data.totalCount };
      }
      return { datas: [], total: 0 };
    });
  },
  // 模糊搜索
  EsQuery(query) {
    let { params, path, paging } = query;
    let queryBody = {
      Type: "*",
      Store: [],
      ItemType: [],
      CmsType: [],
      SysType: ["CmsItem"],
      LinkInfo: [],
      PageQuery: {
        Start: paging?.start || "0",
        Size: paging?.size || "10",
      },
    };
    // 设置不同的Path
    // 如果没有搜索关键字,则只用获取名称
    if (params.length > 0) {
      let data = {
        "||Name": [...params],
        "||tourism_content*": [...params],
        "||tourism_workflow*": [...params],
        "||tourism_notes*": [...params],
        "||tourism_caseIndex*": [...params],
        "||tourism_basicCase*": [...params],
        "||tourism_judgmentAndReasons*": [...params],
        "||tourism_legalIssuesInvolvedInThisCase*": [...params],
        "||tourism_referenceAnswerAndLegalAnalysis*": [...params],
        "||tourism_case*": [...params],
        "||tourism_clause*": [...params],
        "||tourism_unscramble*": [...params],
        "||tourism_specialRemind*": [...params],
        "||tourism_fiction*": [...params],
        "||tourism_authorityNature*": [...params],
        "||tourism_authorityGist*": [...params],
        "||tourism_penaltyGist*": [...params],
        "||tourism_penaltyTerms*": [...params],
        "||tourism_penaltyType*": [...params],
        "||tourism_remarksNote*": [...params],
        "||tourism_keyword*": [...params],
      };
      Object.assign(queryBody, data);
    } else {
      let data = {
        Name: [],
      };
      Object.assign(queryBody, data);
    }
    // 全部搜索  - 单独的某个库
    if (path != "All") {
      let data = {
        Path: [
          {
            Repository: "tourism_tourismLawsAndRegulationsDatabase",
            Path: path,
          },
        ],
      };
      Object.assign(queryBody, data);
    }
    const body = { query: JSON.stringify({ Query: [{ Q1: queryBody }] }) };
    return request({
      url: "/resource/api/ApiEsQuery",
      method: "post",
      data: body,
    }).then((res) => {
      if (res.length > 0) {
        const data = res[0];
        const datas = handleQueryResourceListData({
          datas: data.datas,
          path,
        });
        return { datas, total: data.totalCount };
      }
      return { data: [], total: 0 };
    });
  },
  //获取资源类型
  getCmsTypeByRefCode(data) {
    return request({
      url: "resource/api/ApiGetCmsTypeByRefCode",
      method: "post",
      data,
    });
  },
  //取消cms收藏
  delCmsItemLink(data) {
    return request({
      url: "/resource/api/ApiDelCmsItemLink",
      method: "post",
      data,
    });
  },
  //cms收藏
  collectCmsItem(data) {
    return request({
      url: "/resource/api/ApiAddCmsItemLink",
      method: "post",
      data,
    });
  },
  // 获取cms收藏列表
  getCmsCollectList(data) {
    const body = { query: JSON.stringify({ Query: [{ Q1: data }] }) };
    return request({
      url: "/resource/api/ApiAppUserQuery",
      method: "post",
      data: body,
    });
  },
};
export default resourceApi;
src/assets/js/middleGround/api/store.js
New file
@@ -0,0 +1,903 @@
import request from '@/plugin/axios/index.ts'
import { tokenKey, goodsStore } from '@/assets/js/config'
import { handleQueryResourceListData, handleDetailQueryRequestData } from '../tool'
const storeApi = {
  /*
    **获取商品列表**
    path: 数据路径
    storeInfo: 仓储
    channelInfo: 频道
    subAccess:
    queryType: 检索类型
    paging: 分页
    sort: 排序
    fields: 自定义字段
  */
  getProductList: ({
    path = '',
    storeInfo = goodsStore,
    storeEventIdOrRefCode = '',
    favoriteTypes = '',
    queryType,
    linkType,
    subAccess = [],
    paging = {},
    sort,
    fields,
    filterList,
    coverSize,
    mainProductId,
    handelEBooK
  }) => {
    const query = {
      AccessControl: {
        Path: path,
        StoreRefCode: storeInfo + '',
        Type: queryType || '\\',
        LinkType: linkType || ''
      },
      FavoriteTypes: favoriteTypes ? [favoriteTypes] : [],
      SubAccess: subAccess.length > 0 ? subAccess : [],
      PageQuery: {
        Start: paging.start || '0',
        Size: paging.size || '10'
      },
      SortQuery:
        sort?.length == 0
          ? []
          : sort
            ? [sort]
            : [
                {
                  LinkOrder: 'Desc'
                }
              ],
      CreateDate: [],
      Description: [],
      Name: [],
      Icon: [],
      RefCode: [],
      TypeId: [],
      SysType: [],
      State: [],
      Tag: [],
      BeginDate: [],
      EndDate: [],
      ProductLinkInfo: [],
      AllowDonate: [],
      // DonatePriceList: [],
      StoreEvent: [],
      SubProductCount: [],
      SaleMethod: [],
      SaleMethodValid: [],
      StoreEventIdOrRefCode: storeEventIdOrRefCode,
      ...fields,
      ...filterList
    }
    if (mainProductId) {
      query.AccessControl.MainProductId = mainProductId
    }
    if (handelEBooK) {
      query.ProductCmsQuery = [
        {
          QueryCms: {
            Path: '*',
            Type: '\\',
            Name: [],
            Icon: [],
            TypeId: [],
            RefCode: [],
            ChildrenCount: [],
            ChildrenFolderCount: [],
            CreateDate: [],
            SysType: [],
            SaleMethod: [],
            PageQuery: {
              Start: 0,
              Size: 9999
            },
            ProductLinkInfo: []
          }
        }
      ]
    }
    const body = {
      query: JSON.stringify({
        Query: [
          {
            Q1: query
          }
        ]
      })
    }
    let token = localStorage.getItem(tokenKey)
    let url = token ? '/store/api/ApiQueryProductByAppUser' : '/store/api/ApiQueryProduct'
    return request({
      url: url,
      method: 'post',
      data: body
    }).then((resp) => {
      if (resp.length > 0) {
        const data = resp[0]
        const datas = handleQueryResourceListData({
          datas: data.datas,
          fields,
          path,
          storeInfo,
          coverSize,
          handelEBooK
        })
        return {
          datas,
          total: data.totalCount,
          extraInfos: data.extraInfos?.StoreEvent
        }
      }
      return {
        datas: [],
        total: 0
      }
    })
  },
  /*
    **获取商品详情**
    path: 数据路径
    storeInfo: 仓储
    channelInfo: 频道
    subAccess:
    fields: 自定义字段
    productId: 商品ID
    cmsPath:cmsPath
  */
  getProductDetail: ({
    path = '',
    storeInfo = goodsStore,
    channelInfo = '',
    favoriteTypes = '',
    queryType,
    subAccess = [],
    fields,
    productId,
    cmsPath,
    cmsType,
    coverSize,
    itemId,
    itemIds,
    itemFields,
    linkTypes,
    filterList,
    handelEBooK,
    sort,
    cmsSort,
    source
  }) => {
    const subQuery = {}
    if (cmsPath) {
      subQuery['QueryCms'] = {
        Path: cmsPath + '',
        Type: cmsType || '\\',
        Name: [],
        Icon: [],
        TypeId: [],
        RefCode: [],
        Description: [],
        ChildrenCount: [],
        ChildrenFolderCount: [],
        CreateDate: [],
        SysType: [],
        SaleMethod: [],
        PageQuery: {
          Start: 0,
          Size: 9999
        },
        SortQuery: cmsSort
          ? [cmsSort]
          : [
              {
                ProductLinkOrder: 'Asc'
              }
            ],
        ProductLinkInfo: [],
        ...itemFields
      }
      if (itemId) subQuery['QueryCms']['Id='] = [`${itemId}`]
      if (itemIds) subQuery['QueryCms']['Id='] = itemIds
    } else {
      subQuery['QueryCms'] = {
        Path: '*',
        Type: '\\',
        Name: [],
        Icon: [],
        TypeId: [],
        RefCode: [],
        Description: [],
        ChildrenCount: [],
        ChildrenFolderCount: [],
        CreateDate: [],
        SysType: [],
        SaleMethod: [],
        PageQuery: {
          Start: 0,
          Size: 9999
        },
        ProductLinkInfo: []
      }
    }
    // 获取关联资源
    let linkFields = {}
    if (linkTypes && linkTypes.length) {
      for (let i = 0; i < linkTypes.length; i++) {
        const linkType = linkTypes[i]
        subQuery['QueryLink_' + linkType.linkType] = {
          Path: cmsPath + '',
          Type: '\\',
          Name: [],
          Icon: [],
          TypeId: [],
          RefCode: [],
          Description: [],
          LinkTypes: [linkType.linkType],
          PageQuery: {
            Start: 0,
            Size: 100
          },
          ProductLinkInfo: [],
          ...linkType.fields
        }
        linkFields = {
          ...linkFields,
          ...linkType.fields
        }
      }
    }
    const query = {
      AccessControl: {
        Path: path,
        StoreRefCode: storeInfo + '',
        ChannelRefCode: channelInfo + '',
        Type: queryType || '\\'
      },
      FavoriteTypes: favoriteTypes ? [favoriteTypes] : [],
      SubAccess: subAccess.length > 0 ? subAccess : [],
      PageQuery: {
        Start: '0',
        Size: '1'
      },
      'Id=': [`${productId}`],
      SortQuery: sort
        ? [sort]
        : [
            {
              LinkOrder: 'Desc'
            }
          ],
      CreateDate: [],
      Description: [],
      Name: [],
      Icon: [],
      RefCode: [],
      Description: [],
      TypeId: [],
      SysType: [],
      State: [],
      Tag: [],
      BeginDate: [],
      EndDate: [],
      ProductLinkInfo: [],
      AllowDonate: [],
      DonatePriceList: [],
      StoreEvent: [],
      SaleMethod: [],
      SaleMethodValid: [],
      CmsItemValid: [],
      ProductCmsQuery: [subQuery],
      ...fields,
      ...filterList
    }
    if (productId) query['Id='] = [`${productId}`]
    const body = {
      query: JSON.stringify({
        Query: [
          {
            Q1: query
          }
        ]
      })
    }
    let token = localStorage.getItem(tokenKey)
    let url = token ? '/store/api/ApiQueryProductByAppUser' : '/store/api/ApiQueryProduct'
    return request({
      url: url,
      method: 'post',
      data: body,
      cancelToken: source?.token
    }).then((resp) => {
      if (resp.length > 0) {
        const data = resp[0]
        if (data.datas.length) {
          data.datas[0].subDatas = data.datas[0].cmsDatas
          const datas = handleDetailQueryRequestData({
            productId,
            item: data.datas[0],
            fields,
            itemFields: {
              ...itemFields,
              ...linkFields
            },
            path,
            coverSize,
            handelEBooK
          })
          return {
            datas,
            total: data.totalCount
          }
        } else {
          return {
            datas: [],
            total: 0
          }
        }
      }
      return {
        datas: [],
        total: 0
      }
    })
  },
  // 获取商品详情,不返回 ChildrenCount,ChildrenFolderCount
  // (此接口为了满足不返回 ChildrenCount,ChildrenFolderCount而后续添加的) 不是中台原有的
  getProductDetailNoChildren: ({
    path = '',
    storeInfo = goodsStore,
    channelInfo = '',
    favoriteTypes = '',
    queryType,
    subAccess = [],
    fields,
    productId,
    cmsPath,
    cmsType,
    coverSize,
    itemId,
    itemIds,
    itemFields,
    linkTypes,
    filterList,
    handelEBooK,
    sort,
    cmsSort,
    source
  }) => {
    const subQuery = {}
    if (cmsPath) {
      subQuery['QueryCms'] = {
        Path: cmsPath + '',
        Type: cmsType || '\\',
        Name: [],
        Icon: [],
        TypeId: [],
        RefCode: [],
        Description: [],
        // ChildrenCount: [],
        // ChildrenFolderCount: [],
        CreateDate: [],
        SysType: [],
        SaleMethod: [],
        PageQuery: {
          Start: 0,
          Size: 9999
        },
        SortQuery: cmsSort
          ? [cmsSort]
          : [
              {
                ProductLinkOrder: 'Asc'
              }
            ],
        ProductLinkInfo: [],
        ...itemFields
      }
      if (itemId) subQuery['QueryCms']['Id='] = [`${itemId}`]
      if (itemIds) subQuery['QueryCms']['Id='] = itemIds
    } else {
      subQuery['QueryCms'] = {
        Path: '*',
        Type: '\\',
        Name: [],
        Icon: [],
        TypeId: [],
        RefCode: [],
        Description: [],
        ChildrenCount: [],
        ChildrenFolderCount: [],
        CreateDate: [],
        SysType: [],
        SaleMethod: [],
        PageQuery: {
          Start: 0,
          Size: 9999
        },
        ProductLinkInfo: []
      }
    }
    // 获取关联资源
    let linkFields = {}
    if (linkTypes && linkTypes.length) {
      for (let i = 0; i < linkTypes.length; i++) {
        const linkType = linkTypes[i]
        subQuery['QueryLink_' + linkType.linkType] = {
          Path: cmsPath + '',
          Type: '\\',
          Name: [],
          Icon: [],
          TypeId: [],
          RefCode: [],
          Description: [],
          LinkTypes: [linkType.linkType],
          PageQuery: {
            Start: 0,
            Size: 100
          },
          ProductLinkInfo: [],
          ...linkType.fields
        }
        linkFields = {
          ...linkFields,
          ...linkType.fields
        }
      }
    }
    const query = {
      AccessControl: {
        Path: path,
        StoreRefCode: storeInfo + '',
        ChannelRefCode: channelInfo + '',
        Type: queryType || '\\'
      },
      FavoriteTypes: favoriteTypes ? [favoriteTypes] : [],
      SubAccess: subAccess.length > 0 ? subAccess : [],
      PageQuery: {
        Start: '0',
        Size: '1'
      },
      'Id=': [`${productId}`],
      SortQuery: sort
        ? [sort]
        : [
            {
              LinkOrder: 'Desc'
            }
          ],
      CreateDate: [],
      Description: [],
      Name: [],
      Icon: [],
      RefCode: [],
      Description: [],
      TypeId: [],
      SysType: [],
      State: [],
      Tag: [],
      BeginDate: [],
      EndDate: [],
      ProductLinkInfo: [],
      AllowDonate: [],
      DonatePriceList: [],
      StoreEvent: [],
      SaleMethod: [],
      SaleMethodValid: [],
      CmsItemValid: [],
      ProductCmsQuery: [subQuery],
      ...fields,
      ...filterList
    }
    if (productId) query['Id='] = [`${productId}`]
    const body = {
      query: JSON.stringify({
        Query: [
          {
            Q1: query
          }
        ]
      })
    }
    let token = localStorage.getItem(tokenKey)
    let url = token ? '/store/api/ApiQueryProductByAppUser' : '/store/api/ApiQueryProduct'
    return request({
      url: url,
      method: 'post',
      data: body,
      cancelToken: source?.token
    }).then((resp) => {
      if (resp.length > 0) {
        const data = resp[0]
        if (data.datas.length) {
          data.datas[0].subDatas = data.datas[0].cmsDatas
          const datas = handleDetailQueryRequestData({
            productId,
            item: data.datas[0],
            fields,
            itemFields: {
              ...itemFields,
              ...linkFields
            },
            path,
            coverSize,
            handelEBooK
          })
          return {
            datas,
            total: data.totalCount
          }
        } else {
          return {
            datas: [],
            total: 0
          }
        }
      }
      return {
        datas: [],
        total: 0
      }
    })
  },
  // 获取优惠券列表
  getChannelPromoteCodeList(data) {
    return request({
      url: '/store/api/ApiGetChannelPromoteCodeList',
      method: 'post',
      data
    })
  },
  // 获取用户已领取的优惠券列表
  getPromoteCodeList(data) {
    return request({
      url: '/store/api/ApiGetPromoteCodeList',
      method: 'post',
      data
    })
  },
  // 获取用户浏览排行
  getProductViewRank(data) {
    return request({
      url: '/store/api/ApiGetProductViewRank',
      method: 'post',
      data
    })
  },
  // 获取用户销售排行
  getProductSaleRank(data) {
    return request({
      url: '/store/api/ApiGetProductSaleRank',
      method: 'post',
      data
    })
  },
  // 获取商品可用优惠券
  getProductPromoteCodeList(data) {
    return request({
      url: '/store/api/ApiGetProductPromoteCodeList',
      method: 'post',
      data
    })
  },
  // 获取订单可用优惠券
  getOrderPromoteCodeList(data) {
    return request({
      url: '/store/api/GetOrderPromoteCodeList',
      method: 'post',
      data
    })
  },
  // 获取销售方式可用优惠券
  getSaleMethodPromoteCodeList(data) {
    return request({
      url: '/store/api/GetSaleMethodPromoteCodeList',
      method: 'post',
      data
    })
  },
  // 领取优惠卷
  getPromoteCode(data) {
    return request({
      url: '/store/api/ApiGetPromoteCode',
      method: 'post',
      data
    })
  },
  // 为订单使用优惠券
  updateOrderPromoteCode(data) {
    return request({
      url: '/store/api/UpdateOrderPromoteCode',
      method: 'post',
      data
    })
  },
  // 为销售方式使用优惠券
  updateSaleMethodPromoteCode(data) {
    return request({
      url: '/store/api/UpdateSaleMethodPromoteCode',
      method: 'post',
      data
    })
  },
  // 通过订单号获取订单
  getOrderByOrderNum(data) {
    return request({
      url: '/store/api/GetOrderByOrderNum',
      method: 'post',
      data
    })
  },
  // 创建订单
  initOrder(data) {
    return request({
      url: '/store/api/InitOrder',
      method: 'post',
      data
    })
  },
  // 确认订单
  confirmOrder(data) {
    return request({
      url: '/store/api/ConfirmOrder',
      method: 'post',
      data
    })
  },
  // 取消订单
  cancelOrder(data) {
    return request({
      url: '/store/api/CancelOrder',
      method: 'post',
      data
    })
  },
  // 赞赏
  CreateDonateOrder(data) {
    return request({
      url: '/store/api/CreateDonateOrder',
      method: 'post',
      data
    })
  },
  //获取用户订单列表
  getUserOrderList(data) {
    return request({
      url: '/store/api/GetUserOrderList',
      method: 'post',
      data
    })
  },
  //获取频道下的列表
  getStoreChannelList(data) {
    return request({
      url: '/store/api/ApiGetStoreChannelList',
      method: 'post',
      data
    })
  },
  //获取购物车
  getShoppingCartProductList(data) {
    return request({
      url: '/store/api/ApiGetShoppingCartProductList',
      method: 'post',
      data
    })
  },
  //添加到购物车
  addShoppingCart(data) {
    return request({
      url: '/store/api/ApiAddShoppingCart',
      method: 'post',
      data
    })
  },
  //购物车删除商品
  delShoppingCart(data) {
    return request({
      url: '/store/api/ApiDelShoppingCart',
      method: 'post',
      data
    })
  },
  //从购物车创建订单
  shoppingCartCreateOrder(data) {
    return request({
      url: '/store/api/ApiShoppingCartCreateOrder',
      method: 'post',
      data
    })
  },
  //获取已购买的商品列表
  getPurchasedProductList(data) {
    return request({
      url: '/store/api/ApiGetPurchasedProductList',
      method: 'post',
      data
    })
  },
  //调取微信支付
  makeWeChatPay(data) {
    return request({
      url: '/store/api/MakeWeChatPay',
      method: 'post',
      data
    })
  },
  //调取微信二维码支付
  makeWeChatQrPay(data) {
    return request({
      url: '/store/api/MakeWeChatQrPay',
      method: 'post',
      data
    })
  },
  // 获取激活码详情
  getActiveCode(data) {
    return request({
      url: '/store/api/ApiGetActiveCode',
      method: 'post',
      data
    })
  },
  // 使用激活码
  userActiveCode(data) {
    return request({
      url: '/store/api/ApiUseActiveCode',
      method: 'post',
      data
    })
  },
  // 使用激活码使用记录
  userActiveCodeList(data) {
    return request({
      url: '/store/api/ApiGetUsedActiveCodeList',
      method: 'post',
      data
    })
  },
  // 商品查询类型字段接口
  getProductTypeField(data) {
    return request({
      url: '/store/api/ApiGetProductTypeField',
      method: 'post',
      data
    })
  },
  // 收藏或加入书架
  addProductLink(data) {
    return request({
      url: '/store/api/ApiAddProductLink',
      method: 'post',
      data
    })
  },
  // 取消收藏或移除书架
  delProductLink(data) {
    return request({
      url: '/store/api/ApiDelProductLink',
      method: 'post',
      data
    })
  },
  //购买免费商品
  MakeFreeOrderPay(data) {
    return request({
      url: '/store/api/MakeFreeOrderPay',
      method: 'post',
      data
    })
  },
  // 申请订单开票
  requestOrderInvoice(data) {
    return request({
      url: '/store/api/RequestOrderInvoice',
      method: 'post',
      data
    })
  },
  // 获取用户钱包
  getUserWallet(data) {
    return request({
      url: '/store/api/GetWallet',
      method: 'post',
      data
    })
  },
  // 获取用户钱包记录
  getWalletHistory(data) {
    return request({
      url: '/store/api/GetWalletHistory',
      method: 'post',
      data
    })
  },
  // 通过钱包自动购买
  autoPayWithWallet(data) {
    return request({
      url: '/store/api/AutoPayWithWallet',
      method: 'post',
      data
    })
  },
  // 查询商品所在Store
  getProductStore(data) {
    return request({
      url: '/store/api/ApiGetProductStore',
      method: 'post',
      data
    })
  },
  //根据销售方式查询商品信息
  getProductBySaleMethod(data) {
    return request({
      url: '/store/api/ApiGetProductBySaleMethod',
      method: 'post',
      data
    })
  },
  // 积分兑换
  newOrderPay(data) {
    return request({
      url: '/store/api/NewOrderPay',
      method: 'post',
      data
    })
  },
  // 删除积分订单
  delOrderPay(data) {
    return request({
      url: '/store/api/DelOrderPay',
      method: 'post',
      data
    })
  },
  // 更新积分订单
  UpdateOrderPay(data) {
    return request({
      url: '/store/api/UpdateOrderPay',
      method: 'post',
      data
    })
  }
}
export default storeApi
src/assets/js/middleGround/api/ugc.js
New file
@@ -0,0 +1,117 @@
import request from '@/plugin/axios/index.ts'
import { tokenKey } from '@/assets/js/config.js'
import toolClass from '@/assets/js/toolClass.js'
const ugcApi = {
  // 获取商品点赞Topic
  getProductLikesTopic(data) {
    return request({
      url: localStorage.getItem(tokenKey)
        ? '/ugc/api/ApiAppUserGetProductLikesTopic'
        : '/ugc/api/ApiGetProductLikesTopic',
      method: 'post',
      data
    })
  },
  // 获取商品评论Topic
  getProductCommentTopic(data) {
    return request({
      url: localStorage.getItem(tokenKey)
        ? '/ugc/api/ApiAppUserGetProductCommentTopic'
        : '/ugc/api/ApiGetProductCommentTopic',
      method: 'post',
      data
    })
  },
  // 获取MessageList
  getTopicMessageList(data) {
    return request({
      url: localStorage.getItem(tokenKey)
        ? '/ugc/api/ApiAppUserGetTopicMessageList'
        : '/ugc/api/ApiGetTopicMessageList',
      method: 'post',
      data
    })
  },
  // 获取子MessageList
  getTopicMessageSubList(data) {
    return request({
      url:'/ugc/api/ApiAppUserGetSubMessageList',
      method: 'post',
      data
    })
  },
  // 获取MessageList子message
  getChildTopicMessageList(data) {
    return request({
      url: '/ugc/api/ApiAppUserGetSubMessageList',
      method: 'post',
      data
    })
  },
  // 用户根据消息类型获取列表
  getMessageList(data) {
    return request({
      url: '/ugc/api/ApiGetMessageList',
      method: 'post',
      data
    })
  },
  // 新建Message
  newTopicMessage(data) {
    return request({
      url: '/ugc/api/ApiNewTopicMessage',
      method: 'post',
      data
    })
  },
  // 删除Message
  delTopicMessage(data) {
    return request({
      url: '/ugc/api/ApiDelTopicMessage',
      method: 'post',
      data
    })
  },
  // 更新message
  updateTopicMessage(data) {
    return request({
      url: '/ugc/api/ApiUpdateTopicMessage',
      method: 'post',
      data
    })
  },
  // 获取cms评论
  getCmsItemCommentTopic(data) {
    return request({
      url: '/ugc/api/ApiGetCmsItemCommentTopic',
      method: 'post',
      data
    })
  },
  // 获取用户提交的教学资源
  getProductUserSubmitTopic(data) {
    return request({
      url: '/ugc/api/ApiGetProductUserSubmitTopic',
      method: 'post',
      data
    })
  }
  //更新TOPICMESSAGE
  // updateTopicMessage(data) {
  //   return request({
  //     url: "/ugc/api/ApiUpdateTopicMessage",
  //     method: "post",
  //     data,
  //   });
  // },
}
export default ugcApi
src/assets/js/middleGround/tool.js
New file
@@ -0,0 +1,448 @@
import { requestCtx, appId } from "@/assets/js/config.js";
import defaultImg from "@/assets/images/default-book-img.png";
import defaultBookFair from "@/assets/images/default-bookFair.png"
import bookCover from "@/assets/images/book-cover.png";
import courseIcon from "@/assets/images/courseIcon.png";
import textBookIcon from "@/assets/images/textBookIcon.png";
import moment from "moment";
// 处理列表查询结果
export function handleQueryResourceListData({
  datas,
  fields,
  path,
  storeInfo,
  repositoryInfo,
  coverSize,
  handelEBooK,
}) {
  const dataList = [];
  for (let i = 0; i < datas.length; i++) {
    const item = datas[i];
    // 处理字段
    const _fields = {};
    if (fields != null) {
      for (let fieldKey in fields) {
        if (item.datas[fieldKey]) {
          const values = JSON.parse(item.datas[fieldKey]);
          if (values.length > 0) {
            // 用字段名处理返回的字段值
            if (values[0].Value) {
              _fields[fieldKey] = values[0].Value;
            } else if (values[0].Data) {
              _fields[fieldKey] = values[0].Data.Value;
            }
            item.datas[fieldKey] = values[0];
          }
        }
      }
    }
    const subDatas = {};
    if (item.subDatas) {
      for (let subData of item.subDatas) {
        const tag = subData.queryTag.replace("Query", "");
        subDatas[tag] = subData.datas;
      }
    }
    let obj = {
      ...item,
      id: item.id,
      name: item.datas.Name,
      icon: getPublicImage(
        item.datas.Icon,
        coverSize?.width,
        coverSize?.height,
        storeInfo
      ),
      repositoryInfo: repositoryInfo,
      refCode: item.datas.RefCode === "[]" ? null : item.datas.RefCode,
      state: item.datas.State,
      type: item.datas.Type,
      tag: item.datas.Tag,
      creator: item.datas.Creator ? JSON.parse(item.datas.Creator) : undefined,
      storeInfo: storeInfo,
      linkType: item.datas.LinkType,
      childrenCount: parseInt(item.datas.ChildrenCount ?? "0"),
      childrenFolderCount: parseInt(item.datas.ChildrenFolderCount ?? "0"),
      childrenChannelCount: parseInt(item.datas.ChildrenChannelCount ?? "0"),
      createDate: moment(item.datas.CreateDate).format("YYYY-MM-DD"),
      beginDate: moment(item.datas.BeginDate).format("YYYY-MM-DD"),
      endDate: moment(item.datas.EndDate).format("YYYY-MM-DD"),
      description: item.datas.Description,
      sysType: item.datas.SysType,
      idPath: path + "\\" + item.id,
      typeId: parseInt(item.datas.TypeId),
      linkFile: JSON.parse(item.datas.LinkFile ?? "[]"),
      cmsItemType: item.datas.CmsItemType,
      allowDonate: item.datas.AllowDonate == "True",
      // donatePriceList: JSON.parse(item.datas.DonatePriceList ?? "[]"),
      productLinkInfo: item.datas.ProductLinkInfo ?? "[]",
      storeEvent: JSON.parse(item.datas.StoreEvent ?? "[]"),
      linkInfo: JSON.parse(item.datas.LinkInfo ?? "[]"),
      saleMethod: JSON.parse(item.datas.SaleMethod ?? "[]"),
      subProductCount: parseInt(item.datas.SubProductCount),
      ..._fields,
      datas: item.datas,
      subDatas,
    };
    // 统一处理价格
    if (obj.defaultSaleMethod) {
      if (handelEBooK) {
        // 获取随书资源的销售方式
        let saleMethod = [];
        try {
          saleMethod = obj.cmsDatas[0].datas.find(
            (item) => item.datas.RefCode == "tourism_accompanyingResources"
          ).datas.SaleMethod;
          saleMethod = JSON.parse(saleMethod);
        } catch (error) {
          saleMethod = [];
        }
        if (saleMethod.length) {
          Object.keys(saleMethod[0]).map((key) => {
            let newKey = key.replace(key[0], key[0].toLowerCase());
            saleMethod[0][newKey] = saleMethod[0][key];
            delete saleMethod[0][key];
          });
          obj.defaultSaleMethod = saleMethod[0];
          obj.defaultSaleMethodId = saleMethod[0].id;
          obj.alreadyBuy =
            obj.purchasedSaleMethodIdList.indexOf(obj.defaultSaleMethodId) > -1;
        }
      }
      if (obj.defaultSaleMethod.allowEvent && obj.storeEvent.length) {
        // 已参加活动,获取有效活动并计算价格
        let time = new Date().getTime();
        // 过滤过期活动
        let event = obj.storeEvent.filter((item) => {
          let endTime = new Date(item.EndDate).getTime();
          return endTime > time;
        });
        // 只处理一条有效活动
        if (event.length) {
          obj.price = (obj.defaultSaleMethod.price * event[0].Value).toFixed(2);
          obj.oldPrice = obj.defaultSaleMethod.price;
          obj.storeEventId = event[0].Id;
          if (
            moment().format("YYYY-MM-DD") <
            moment(obj.defaultSaleMethod.endDate).format("YYYY-MM-DD")
          ) {
            obj.defaultSaleMethodState = "Normal";
          } else {
            obj.defaultSaleMethodState = "Beyond";
          }
        }
      } else {
        if (
          moment().format("YYYY-MM-DD") <
          moment(obj.defaultSaleMethod.endDate).format("YYYY-MM-DD")
        ) {
          obj.defaultSaleMethodState = "Normal";
        } else {
          obj.defaultSaleMethodState = "Beyond";
        }
        obj.price = obj.defaultSaleMethod.price;
        obj.oldPrice = obj.defaultSaleMethod.virtualPrice;
      }
    }
    dataList.push(obj);
  }
  return dataList;
}
// 处理详情查询结果
export function handleDetailQueryRequestData({
  productId,
  item,
  fields,
  path,
  coverSize,
  itemFields,
  handelEBooK,
}) {
  item.fileMap = {};
  let itemFieldsData = [];
  for (const key in itemFields) {
    itemFieldsData.push(key);
  }
  let fieldsData = [];
  for (const key in fields) {
    fieldsData.push(key);
  }
  for (let i = 0; i < fieldsData.length; i++) {
    const field = fieldsData[i];
    item.datas[field] = JSON.parse(item.datas[field]);
    const datas = item.datas[field];
    if (datas.length > 0) {
      if (datas[0].Value) {
        item[field] = datas[0].Value;
        if (datas[0].Data.FileLinkList && datas[0].Data.FileLinkList.length) {
          item.fileMap = {
            ...item.fileMap,
            ...handleLinkFileInfo(
              datas[0].Data.FileLinkList.map((item) => {
                return {
                  ...item.File,
                  ...item,
                };
              })
            ),
          };
        }
      } else if (datas[0].Data) {
        item[field] = datas[0].Data.Value;
        if (datas[0].Data.FileLinkList && datas[0].Data.FileLinkList.length) {
          item.fileMap = {
            ...item.fileMap,
            ...handleLinkFileInfo(
              datas[0].Data.FileLinkList.map((item) => {
                return {
                  ...item.File,
                  ...item,
                };
              })
            ),
          };
        }
      }
    }
  }
  // 处理cms资源
  const subDatas = item.subDatas;
  const linkItemsMap = {};
  if (subDatas) {
    for (const sdata of subDatas) {
      const tag = sdata.queryTag;
      for (const subItem of sdata.datas) {
        convertCmsItemBase(subItem, coverSize, handelEBooK);
        subItem.fileMap = {};
        for (let i = 0; i < itemFieldsData.length; i++) {
          const itemField = itemFieldsData[i];
          try {
            subItem.datas[itemField] = JSON.parse(subItem.datas[itemField]);
          } catch (error) {
            subItem.datas[itemField] = [];
          }
          const itemDatas = subItem.datas[itemField];
          if (itemDatas.length > 0) {
            if (itemDatas[0].Value) {
              subItem[itemField] = itemDatas[0].Value;
              if (itemDatas[0].FileList && itemDatas[0].FileList.length) {
                subItem.fileMap = {
                  ...subItem.fileMap,
                  ...handleLinkFileInfo(itemDatas[0].FileList),
                };
              }
            } else if (itemDatas[0].Data) {
              subItem[itemField] = itemDatas[0].Data.Value;
              if (
                itemDatas[0].Data.FileList &&
                itemDatas[0].Data.FileList.length
              ) {
                subItem.fileMap = {
                  ...subItem.fileMap,
                  ...handleLinkFileInfo(itemDatas[0].Data.FileList),
                };
              }
            } else if (itemDatas[0].CmsItemData) {
              subItem[itemField] = itemDatas[0].CmsItemData.Value;
              if (
                itemDatas[0].CmsItemData.FileList &&
                itemDatas[0].CmsItemData.FileList.length
              ) {
                subItem.fileMap = {
                  ...subItem.fileMap,
                  ...handleLinkFileInfo(itemDatas[0].CmsItemData.FileList),
                };
              }
            }
          }
        }
        if (subItem.productLinkInfo && subItem.productLinkInfo.length) {
          let itemProductLinkInfo = subItem.productLinkInfo.find(citem => citem.ProductId == productId)
          subItem.productLinkPath =
            itemProductLinkInfo?.LinkPath +
            "\\" +
            itemProductLinkInfo?.CmsItemId;
        }
        if (subItem.linkInfo && subItem.linkInfo.length)
          subItem.linkPath =
            subItem.linkInfo[0].LinkPath + "\\" + subItem.linkInfo[0].CmsItemId;
      }
      linkItemsMap[tag] = sdata.datas;
    }
  }
  convertCmsItemBase(item, coverSize, handelEBooK);
  item.idPath = path + "\\" + item.id;
  item.subItems = linkItemsMap;
  return item;
}
const handleLinkFileInfo = (linkList) => {
  let linkFileMap = {};
  for (let z = 0; z < linkList.length; z++) {
    const linkItem = linkList[z];
    linkFileMap[linkItem.Md5] = {
      linkType: linkItem.LinkType,
      extension: linkItem.Extension,
      fileName: linkItem.FileName,
      fileType: linkItem.Type,
      md5: linkItem.Md5,
      icon: linkItem.Icon,
      size: linkItem.Size,
      // metaData: JSON.parse(linkItem.MetaData ?? "{}"),
      order: linkItem.Order,
      protectType: linkItem.ProtectType,
    };
  }
  return linkFileMap;
};
const convertCmsItemBase = (item, coverSize, handelEBooK) => {
  item.name = item.datas.Name;
  item.description = item.datas.Description;
  item.refCode = item.datas.RefCode;
  item.state = item.datas.State;
  item.type = item.datas.Type;
  item.tag = item.datas.Tag;
  item.typeId = parseInt(item.datas.TypeId);
  item.icon = item.datas.Icon,
  // item.icon = getPublicImage(
  //   item.datas.Icon,
  //   coverSize?.width,
  //   coverSize?.height
  // );
  item.sysType = item.datas.SysType;
  item.linkFile = JSON.parse(item.datas.LinkFile ?? "[]");
  item.linkType = item.datas.LinkType;
  item.linkAppId = parseInt(item.datas.LinkAppId);
  item.linkStoreId = parseInt(item.datas.LinkStore);
  item.linkRepoId = item.datas.LinkRepository;
  item.childrenCount = parseInt(item.datas.ChildrenCount ?? "0");
  (item.childrenFolderCount = parseInt(item.datas.ChildrenFolderCount ?? "0")),
    (item.childrenChannelCount = parseInt(
      item.datas.ChildrenChannelCount ?? "0"
    )),
    (item.linkId = parseInt(item.datas.LinkId));
  item.linkOrg = JSON.parse(item.datas.LinkOrg ?? "[]")[0];
  item.linkDepartment = JSON.parse(item.datas.LinkDepartment ?? "[]")[0];
  item.linkInfo = JSON.parse(item.datas.LinkInfo ?? "[]");
  item.productLinkInfo = JSON.parse(item.datas.ProductLinkInfo ?? "[]");
  item.saleMethod = JSON.parse(item.datas.SaleMethod ?? "[]");
  item.allowDonate = item.datas.AllowDonate == "True";
  // item.donatePriceList = JSON.parse(item.datas.DonatePriceList ?? "[]");
  item.createDate = moment(item.datas.CreateDate).format("YYYY-MM-DD");
  item.beginDate = moment(item.datas.BeginDate).format("YYYY-MM-DD");
  item.endDate = moment(item.datas.EndDate).format("YYYY-MM-DD");
  item.storeEvent = JSON.parse(item.datas.StoreEvent ?? "[]");
  // 统一处理价格
  if (item.defaultSaleMethod) {
    if (handelEBooK) {
      // 获取随书资源的销售方式
      let saleMethod = item.cmsDatas[0].datas.find(
        (item) => item.refCode == "tourism_accompanyingResources"
      ).saleMethod;
      if (saleMethod && saleMethod.length > 0) {
        Object.keys(saleMethod[0]).map((key) => {
          let newKey = key.replace(key[0], key[0].toLowerCase());
          saleMethod[0][newKey] = saleMethod[0][key];
          delete saleMethod[0][key];
        });
        item.defaultSaleMethod = saleMethod[0];
        item.defaultSaleMethodId = saleMethod[0].id;
        item.alreadyBuy =
          item.purchasedSaleMethodIdList.indexOf(item.defaultSaleMethodId) > -1;
      }
    }
    if (item.defaultSaleMethod.allowEvent && item.storeEvent.length) {
      // 已参加活动,获取有效活动并计算价格
      let time = new Date().getTime();
      // 过滤过期活动
      let event = item.storeEvent.filter((item) => {
        let endTime = new Date(item.EndDate).getTime();
        return endTime > time;
      });
      // 只处理一条有效活动
      if (event.length) {
        item.price = (item.defaultSaleMethod.price * event[0].Value).toFixed(2);
        item.oldPrice = item.defaultSaleMethod.price;
        if (
          moment().format("YYYY-MM-DD") <
          moment(item.defaultSaleMethod.endDate).format("YYYY-MM-DD")
        ) {
          item.defaultSaleMethodState = "Normal";
        } else {
          item.defaultSaleMethodState = "Beyond";
        }
        item.storeEventId = event[0].Id;
      }
    } else {
      item.price = item.defaultSaleMethod.price;
      item.oldPrice = item.defaultSaleMethod.virtualPrice;
      if (
        moment().format("YYYY-MM-DD") <
        moment(item.defaultSaleMethod.endDate).format("YYYY-MM-DD")
      ) {
        item.defaultSaleMethodState = "Normal";
      } else {
        item.defaultSaleMethodState = "Beyond";
      }
    }
  }
};
export function getTopicMsgCmsItemFile(fileType, fileList) {
  let obj = {};
  fileType.forEach((item) => {
    item.sequenceNum = item.config ? JSON.parse(item.config).uuid : "";
    fileList.forEach((e) => {
      if (item.sequenceNum == e.sequenceNum) {
        try {
          if (e.fileLinkList.length > 0) {
            for (let i = 0; i < e.fileLinkList.length; i++) {
              const ele = e.fileLinkList[i];
              ele.name = ele.file.fileName;
              ele.md5 = ele.file.md5;
              ele.status = "success";
            }
            obj[item.typeField.refCode] = e.fileLinkList;
          } else {
            const val = JSON.parse(e.value);
            obj[item.typeField.refCode] = val;
          }
        } catch (error) {
          obj[item.typeField.refCode] = e.value;
        }
      }
    });
  });
  return obj;
}
// 获取不受保护的图片
export function getPublicImage(md5, width, height,storeInfo) {
  let src = null;
  if (md5) {
    src = requestCtx + `/file/GetPreViewImage?md5=${md5}`;
  } else {
    if(storeInfo == 'jsek_bookFair') {
      // return defaultBookFair;
      return
    }else if(storeInfo == `defaultGoodsStore${appId}`){
      return bookCover;
    }else if(storeInfo == 'jsek_digitalCourses'){
      return courseIcon;
    }else if(storeInfo == 'jsek_digitalTextbooks'){
      return textBookIcon;
    }else{
      return ""
    }
  }
  if (width) src += `&width=${width}`;
  if (height) src += `&height=${height}`;
  return src;
}
src/assets/js/toolClass.js
New file
@@ -0,0 +1,467 @@
import SparkMD5 from 'spark-md5'
import { getPublicImage } from '@/assets/js/middleGround/tool.js'
// import moment from "moment";
var tool = {
  secondToTime(second) {
    var minute = Math.floor(second / 60)
    var sec = second % 60
    var time
    if (second < 60) {
      time = second + '"'
    } else {
      time = sec === 0 ? minute + "'" : minute + "'" + sec + '"'
    }
    return time
  },
  setCookie: function (c_name, value, expiredays, path) {
    var exdate = new Date()
    exdate.setDate(exdate.getDate() + expiredays)
    document.cookie =
      c_name +
      '=' +
      escape(value) +
      (expiredays == null ? '' : ';expires=' + exdate.toGMTString()) +
      (path ? ';path=' + path : '')
  },
  getCookie: function (c_name) {
    if (document.cookie.length > 0) {
      var c_start = document.cookie.indexOf(c_name + '=')
      if (c_start != -1) {
        c_start = c_start + c_name.length + 1
        var c_end = document.cookie.indexOf(';', c_start)
        if (c_end == -1) c_end = document.cookie.length
        return unescape(document.cookie.substring(c_start, c_end))
      }
    }
    return ''
  },
  delCookie: function (name) {
    var exp = new Date()
    exp.setTime(exp.getTime() - 1)
    var cval = tool.getCookie(name)
    if (cval != null) document.cookie = name + '=' + cval + ';expires=' + exp.toGMTString()
  },
  // 强制保留2位小数,如:2,会在2后面补上00.即2.00
  toDecimal2(x) {
    var f
    f = parseFloat(x)
    if (isNaN(f)) {
      return false
    }
    f = Math.round(x * 100) / 100
    var s = f.toString()
    var rs = s.indexOf('.')
    if (rs < 0) {
      rs = s.length
      s += '.'
    }
    while (s.length <= rs + 2) {
      s += '0'
    }
    return s
  },
  formateTime(date) {
    var newDate = new Date(+new Date(date) + 8 * 3600 * 1000)
      .toISOString()
      .replace(/T/g, ' ')
      .replace(/\.[\d]{3}Z/, '')
    var time = new Date(newDate)
    return time.getTime()
  }
}
// 处理订单记录
// export function setOrderList(res) {
//   // 获取当前年份的开始时间
//   let currentTimestamp = moment().startOf("year");
//   let arr = [];
//   for (let i = 0; i < res.length; i++) {
//     const item = res[i];
//     // 发票状态为审核中或者审核失败,将item选中状态设置选中。
//     // UI控制禁用(显示的效果为 选中并且禁用)
//     if (item.invoiceInfo) {
//       item.checked = true;
//     } else {
//       item.checked = false;
//     }
//     // 判断是否超出申请发票的日期
//     item.exceedingTheSpecifiedTime = moment(item.createDate).isBefore(
//       currentTimestamp
//     );
//     if (item.saleMethodLinks.length > 0) {
//       let itemName = null;
//       let itemIcon = null;
//       let cmsItemList = null;
//       try {
//         cmsItemList = item.saleMethodLinks[0].orderSaleMethod.cmsItemList[0];
//       } catch (error) {
//         cmsItemList = null;
//       }
//       if (cmsItemList && cmsItemList.icon) {
//         itemName = cmsItemList.name;
//         itemIcon = cmsItemList.icon;
//       } else {
//         itemName = item.saleMethodLinks[0].orderSaleMethod.product.name;
//         itemIcon = item.saleMethodLinks[0].orderSaleMethod.product.icon;
//       }
//       item.saleMethodLinks[0].title = itemName;
//       item.saleMethodLinks[0].icon = getPublicImage(itemIcon);
//     } else {
//       const itemIcon = require("@/assets/images/bookCity/place_img.png");
//       const saleMethodLink = [];
//       const obj = {
//         icon: itemIcon,
//         orderSaleMethod: {
//           price: item.payPrice,
//         },
//       };
//       saleMethodLink.push(obj);
//       item.saleMethodLinks = saleMethodLink;
//     }
//     if (item.state == "Success") {
//       item.CustomState = "支付成功";
//     }
//     if (item.state == "Cancel") {
//       item.CustomState = "取消支付";
//     }
//     if (item.state == "WaitPay") {
//       item.CustomState = "等待支付";
//     }
//     if (item.state == "WaitDeliver") {
//       item.CustomState = "正在支付";
//     }
//     arr.push(item);
//   }
//   return arr;
// }
//处理表单提交数据
export function worksData(res) {
  let arr = []
  for (let i = 0; i < res.length; i++) {
    const item = res[i]
    if (item.typeField) {
      if (item.typeField.config) {
        item.typeField.options = JSON.parse(item.typeField.config).option
      }
      arr.push(item.typeField)
    }
  }
  return arr
}
export function worksDataBytool(res, value, linkList) {
  let arr = []
  let nrr = []
  if (linkList && linkList.length > 0) {
    linkList.forEach((e) =>
      nrr.push({
        linkProtectType: e.linkProtectType,
        linkType: e.linkType,
        md5: e.md5,
        fileName: e.fileName ?? '',
        extension: e.extension ?? ''
      })
    )
  }
  res.forEach((item) => {
    const obj = {
      baseType: item.typeField.baseType,
      order: 0,
      typeFieldId: item.typeField.id,
      sequenceNum: item.config ? JSON.parse(item.config).uuid : '',
      newDataAndFileLinkListRequest: []
    }
    for (let k in value) {
      if (item.typeField.refCode === k) {
        if (item.typeField.type == 'File') {
          try {
            obj.strValue = JSON.stringify(value[k].map((citem) => citem.md5))
          } catch (error) {
            obj.strValue = ''
          }
          obj.newDataAndFileLinkListRequest = nrr
        } else {
          if (typeof value[k] == 'object') {
            obj.strValue = JSON.stringify(value[k])
          } else {
            if (obj.baseType === 'String') {
              obj.strValue = value[k] + ''
            } else if (obj.baseType === 'Text') {
              obj.textValue = value[k] + ''
            } else {
              obj.strValue = value[k] + ''
            }
          }
        }
      }
    }
    // if (obj.strValue || obj.textValue) {
    arr.push(obj)
    // }
  })
  return arr
}
export function UpdateworksDataBytool(initData, res, value, linkList) {
  let arr = []
  let newArr = []
  for (let i = 0; i < initData.length; i++) {
    const ele = initData[i]
    for (let j = 0; j < res.length; j++) {
      const item = res[j]
      if (item.sequenceNum == ele.sequenceNum) {
        item.refCode = ele.typeField.refCode
      }
    }
  }
  initData.forEach((citem) => {
    const updateOldData = res.find((f) => f.sequenceNum == citem.sequenceNum)
    if (updateOldData) {
      const obj = {
        baseType: citem.typeField.baseType,
        order: 0,
        id: updateOldData.id,
        typeFieldId: citem.typeField.id,
        sequenceNum: citem.sequenceNum,
        setDataAndFileLinkListRequest: []
      }
      for (let k in value) {
        if (citem.typeField.refCode === k) {
          if (typeof value[k] == 'object' && k != 'region') {
            obj.strValue = JSON.stringify(linkList)
            obj.setDataAndFileLinkListRequest = linkList
          } else if (typeof value[k] == 'object' && k == 'region') {
            obj.strValue = value[k]?.join('/')
            obj.setDataAndFileLinkListRequest = [{ area: value[k] }]
          } else {
            obj.strValue = value[k].toString()
          }
        }
      }
      if (obj.strValue) {
        arr.push(obj)
      }
    } else {
      const newObj = {
        baseType: citem.typeField.baseType,
        order: 0,
        typeFieldId: citem.typeField.id,
        sequenceNum: citem.sequenceNum,
        setDataAndFileLinkListRequest: []
      }
      for (let k in value) {
        if (citem.typeField.refCode === k) {
          if (typeof value[k] == 'object') {
            newObj.strValue = JSON.stringify(linkList)
            newObj.setDataAndFileLinkListRequest = linkList
          } else {
            newObj.strValue = value[k].toString()
          }
        }
      }
      if (newObj.strValue) {
        newArr.push(newObj)
      }
    }
  })
  return {
    updateData: arr,
    newData: newArr
  }
}
export function download(url) {
  const iframe = document.createElement('iframe')
  iframe.setAttribute('hidden', 'hidden')
  document.body.appendChild(iframe)
  iframe.onload = () => {
    if (iframe) {
      iframe.setAttribute('src', 'about:blank')
    }
  }
  iframe.setAttribute('src', url)
}
/**
 * 获取一个UUID
 * @param len
 * @param radix
 * @returns {string}
 */
export function uuid(len = 32, radix = 16) {
  const chars = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'.split('')
  let uuid = [],
    i
  radix = radix || chars.length
  if (len) {
    // Compact form
    for (i = 0; i < len; i++) uuid[i] = chars[0 | (Math.random() * radix)]
  } else {
    // rfc4122, version 4 form
    let r
    // rfc4122 requires these characters
    uuid[8] = uuid[13] = uuid[18] = uuid[23] = '-'
    uuid[14] = '4'
    // Fill in random data.  At i==19 set the high bits of clock sequence as
    // per rfc4122, sec. 4.1.5
    for (i = 0; i < 36; i++) {
      if (!uuid[i]) {
        r = 0 | (Math.random() * 16)
        uuid[i] = chars[i === 19 ? (r & 0x3) | 0x8 : r]
      }
    }
  }
  return uuid.join('')
}
export function getFileMd5(file, chunkSize) {
  return new Promise((resolve, reject) => {
    let blobSlice = File.prototype.slice || File.prototype.mozSlice || File.prototype.webkitSlice
    let chunks = Math.ceil(file.size / chunkSize)
    let currentChunk = 0
    let spark = new SparkMD5.ArrayBuffer()
    let fileReader = new FileReader()
    fileReader.onload = function (e) {
      spark.append(e.target.result)
      currentChunk++
      if (currentChunk < chunks) {
        loadNext()
      } else {
        const md5 = spark.end()
        resolve(md5)
      }
    }
    fileReader.onerror = function (e) {
      reject(e)
    }
    function loadNext() {
      let start = currentChunk * chunkSize
      let end = start + chunkSize
      if (end > file.size) {
        end = file.size
      }
      fileReader.readAsArrayBuffer(blobSlice.call(file, start, end))
    }
    loadNext()
  })
}
// 处理时间,用于显示音视频当前时间
// export function realFormatSecond(time) {
//   let duration = parseInt(time);
//   let minute = parseInt(duration / 60);
//   let sec = (duration % 60) + "";
//   let isM0 = ":";
//   if (minute == 0) {
//     minute = "00";
//   } else if (minute < 10) {
//     minute = "0" + minute;
//   }
//   if (sec.length == 1) {
//     sec = "0" + sec;
//   }
//   return minute + isM0 + sec;
// }
// export function parseHtml(content) {
//   const tagReg =
//     /<\/?div[^>]*>|<\/?span[^>]*>|<\/?table[^>]*>|<\/?th[^>]*>|<\/?thead>|<\/?tbody>|<\/?tr>|<\/?td[^>]*>|<br[^>]*>|<\/?p[^>]*>|<\/?sub>|<\/?sup>|<\/?font[^>]*>|<img[^>]*>|<\/?a[^>]*>|\n|\\n/gi;
//   const escapeReg =
//     /&(lt|gt|le|ge|nbsp|amp|quot|times|Alpha|Beta|Gamma|Delta|Epsilon|Zeta|Eta|Theta|Iota|Kappa|Lambda|MU|NU|Xi|Omicron|Pi|Rho|Sigma|Tau|Upsilon|Phi|Chi|Psi|Omega|alpha|beta|gamma|delta|epsilon|zeta|eta|theta|iota|kappa|lambda|mu|nu|xi|omicron|pi|rho|sigmaf|sigma|tau|upsilon|phi|chi|psi|omega|thetasym|upsih|piv|circ|tilde|ndash|permil|lsquo|rsquo|ldquo|rdquo|prime);/gi;
//   const escapeElements = {
//     lt: "<",
//     gt: ">",
//     le: "≤",
//     ge: "≥",
//     nbsp: " ",
//     amp: "&",
//     quot: '""',
//     times: "×",
//     Alpha: "Α",
//     Beta: "Β",
//     Gamma: "Γ",
//     Delta: "Δ",
//     Epsilon: "Ε",
//     Zeta: "Ζ",
//     Eta: "Η",
//     Theta: "Θ",
//     Iota: "Ι",
//     Kappa: "Κ",
//     Lambda: "Λ",
//     Mu: "Μ",
//     Nu: "Ν",
//     Xi: "Ξ",
//     Omicron: "Ο",
//     Pi: "Π",
//     Rho: "Ρ",
//     Sigma: "Σ",
//     Tau: "Τ",
//     Upsilon: "Υ",
//     Phi: "Φ",
//     Chi: "Χ",
//     Psi: "Ψ",
//     Omega: "Ω",
//     alpha: "α",
//     beta: "β",
//     gamma: "γ",
//     delta: "δ",
//     epsilon: "ε",
//     zeta: "ζ",
//     eta: "η",
//     theta: "θ",
//     iota: "ι",
//     kappa: "κ",
//     lambda: "λ",
//     mu: "μ",
//     nu: "ν",
//     xi: "ξ",
//     omicron: "ο",
//     pi: "π",
//     rho: "ρ",
//     sigmaf: "ς",
//     sigma: "σ",
//     tau: "τ",
//     upsilon: "υ",
//     phi: "φ",
//     chi: "χ",
//     psi: "ψ",
//     omega: "ω",
//     thetasym: "ϑ",
//     upsih: "ϒ",
//     piv: "ϖ",
//     circ: "ˆ",
//     tilde: "˜",
//     ndash: "–",
//     permil: "‰",
//     lsquo: "‘",
//     rsquo: "’",
//     ldquo: "“",
//     rdquo: "”",
//     prime: "′",
//   };
//   const contentWithoutTag = content.replace(tagReg, "");
//   const contentWithOnlyOneSpace = contentWithoutTag.replace(/ {2,}/g, " ");
//   return contentWithOnlyOneSpace.replace(
//     escapeReg,
//     (all, t) => escapeElements[t]
//   );
// }
export default {
  ...tool,
  uuid,
  getFileMd5,
  worksDataBytool,
  UpdateworksDataBytool,
  getPublicImage,
  worksData
  // parseHtml,
}
src/assets/js/userAction.js
New file
@@ -0,0 +1,135 @@
import config from "@/assets/js/config.js";
import jobApi from "./middleGround/api/job"; // newJobWithNewView // newSession,
export function setSessionGuid(type, id) {
  var cityCode = null;
  var SnIp = null;
  try {
    // eslint-disable-next-line
    SnIp = window.returnCitySN;
  } catch (error) {
    SnIp = null;
    console.log(error);
  }
  if (SnIp != undefined && SnIp != null) {
    cityCode = SnIp;
  } else {
    cityCode = {
      cip: "0.0.0.0",
      cname: "未知",
    };
  }
  const _city = cityCode.cname.substring(3);
  const _province = cityCode.cname.substring(0, 3);
  const params = {
    appRefCode: config.appRefCode,
    hostName: config.requestCtx,
    ipAddress: cityCode.cip,
    browser: myBrowser(),
    os: navigator.platform,
    device: "pc",
    province: _province,
    city: _city ? _city : _province,
  };
  jobApi.newSession(params).then(res => {
    storage.set("sessionGuid", res, 30);
    setNewView(type, id);
  });
}
export const storage = {
  /*
   * set 存储方法
   * @ param {String}     key 键
   * @ param {String}     value 值,
   * @ param {String}     expired 过期时间,以分钟为单位,非必须
   */
  set(key, val, expired) {
    if (typeof val !== "string") {
      val = JSON.stringify(val);
    }
    window.sessionStorage.setItem(key, val);
    if (expired) {
      window.sessionStorage.setItem(
        `${key}__expires__`,
        `${Date.now() + 1000 * 60 * expired}`
      );
    }
  },
  /*
   * get 获取方法
   * @ param {String}     key 键
   * @ param {String}     expired 存储时为非必须字段,所以有可能取不到,默认为 Date.now+1
   */
  get(key) {
    const expired =
      window.sessionStorage.getItem(`${key}__expires__`) || Date.now + 1;
    const now = Date.now();
    if (now >= expired) {
      window.sessionStorage.removeItem(key);
      return;
    }
    let val = window.sessionStorage.getItem(key);
    try {
      val = JSON.parse(val);
    } catch (e) {
      return e;
    }
    return val;
  },
};
function myBrowser() {
  const userAgent = navigator.userAgent; //取得浏览器的userAgent字符串
  const isOpera = userAgent.indexOf("Opera") > -1;
  if (isOpera) {
    //判断是否Opera浏览器
    return "Opera";
  }
  if (userAgent.indexOf("Firefox") > -1) {
    //判断是否Firefox浏览器
    return "Firefox";
  }
  if (userAgent.indexOf("Chrome") > -1) {
    return "Chrome";
  }
  if (userAgent.indexOf("Safari") > -1) {
    //判断是否Safari浏览器
    return "Safari";
  }
  if (
    userAgent.indexOf("compatible") > -1 &&
    userAgent.indexOf("MSIE") > -1 &&
    !isOpera
  ) {
    //判断是否IE浏览器
    return "IE";
  }
  return "";
}
export function setNewView(type, id) {
  if (!sessionStorage.getItem("sessionGuid")) {
    setSessionGuid(type, id);
  }
  const sessionGuid = sessionStorage.getItem("sessionGuid");
  const fromPath = sessionStorage.getItem("fromPath");
  const toPath = sessionStorage.getItem("toPath");
  if (sessionGuid) {
    let params = {
      sessionGuid: sessionGuid,
      appRefCode: config.appRefCode,
      type: "View",
      url: toPath == null ? "/" : toPath,
      ref: fromPath == null ? "/" : fromPath,
    };
    if (id) {
      params[type] = id;
    }
    jobApi.newJobWithNewView(params).then(res => {});
  }
}
src/assets/vue.svg
New file
@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" class="iconify iconify--logos" width="37.07" height="36" preserveAspectRatio="xMidYMid meet" viewBox="0 0 256 198"><path fill="#41B883" d="M204.8 0H256L128 220.8L0 0h97.92L128 51.2L157.44 0h47.36Z"></path><path fill="#41B883" d="m0 0l128 220.8L256 0h-51.2L128 132.48L50.56 0H0Z"></path><path fill="#35495E" d="M50.56 0L128 133.12L204.8 0h-47.36L128 51.2L97.92 0H50.56Z"></path></svg>
src/components/HelloWorld.vue
New file
@@ -0,0 +1,43 @@
<script setup>
import { ref } from 'vue'
defineProps({
  msg: String,
})
const count = ref(0)
</script>
<template>
  <h1>{{ msg }}</h1>
  <div class="card">
    <button type="button" @click="count++">count is {{ count }}</button>
    <p>
      Edit
      <code>components/HelloWorld.vue</code> to test HMR
    </p>
  </div>
  <p>
    Check out
    <a href="https://vuejs.org/guide/quick-start.html#local" target="_blank"
      >create-vue</a
    >, the official Vue + Vite starter
  </p>
  <p>
    Learn more about IDE Support for Vue in the
    <a
      href="https://vuejs.org/guide/scaling-up/tooling.html#ide-support"
      target="_blank"
      >Vue Docs Scaling up Guide</a
    >.
  </p>
  <p class="read-the-docs">Click on the Vite and Vue logos to learn more</p>
</template>
<style scoped>
.read-the-docs {
  color: #888;
}
</style>
src/components/SearchBar.vue
New file
@@ -0,0 +1,29 @@
<template>
  <div class="search-container">
    <el-input
      v-model="searchText"
      placeholder="搜索..."
      prefix-icon="Search"
      clearable
      @input="handleSearch"
    />
  </div>
</template>
<script setup lang="ts">
import { ref } from 'vue'
const searchText = ref('')
const emit = defineEmits(['search'])
const handleSearch = () => {
  emit('search', searchText.value)
}
</script>
<style lang="less" scoped>
.search-container {
  padding: 16px;
  border-bottom: 1px solid #eee;
}
</style>
src/components/TreeMenu.vue
New file
@@ -0,0 +1,127 @@
<template>
  <div class="tree-menu">
    <SearchBar @search="handleSearch" />
    <el-tree
      ref="treeRef"
      :data="filteredData"
      :props="defaultProps"
      :filter-node-method="filterNode"
      default-expand-all
      @node-click="handleNodeClick"
    >
      <template #default="{ node, data }">
        <span class="custom-tree-node">
          <el-icon v-if="data.icon"><component :is="data.icon" /></el-icon>
          <span>{{ node.label }}</span>
        </span>
      </template>
    </el-tree>
  </div>
</template>
<script setup lang="ts">
import { ref, watch } from 'vue'
import { useRouter } from 'vue-router'
import SearchBar from './SearchBar.vue'
import { Document, FolderOpened } from '@element-plus/icons-vue'
const router = useRouter()
const treeRef = ref()
interface TreeNode {
  label: string
  path?: string
  icon?: string
  children?: TreeNode[]
}
const treeData = ref<TreeNode[]>([
  {
    label: '模型管理',
    icon: 'FolderOpened',
    children: [
      {
        label: '机构模型',
        path: '/mechanism',
        icon: 'Document'
      },
      {
        label: '运动学模型',
        path: '/kinematic',
        icon: 'Document'
      }
    ]
  },
  {
    label: '可视化仿真',
    icon: 'FolderOpened',
    children: [
      {
        label: '仿真配置',
        path: '/simulation-config',
        icon: 'Document'
      },
      {
        label: '仿真结果',
        path: '/simulation-result',
        icon: 'Document'
      }
    ]
  },
  {
    label: '系统管理',
    icon: 'FolderOpened',
    children: [
      {
        label: '用户管理',
        path: '/system/user',
        icon: 'Document'
      },
      {
        label: '权限设置',
        path: '/system/permission',
        icon: 'Document'
      }
    ]
  }
])
const defaultProps = {
  children: 'children',
  label: 'label'
}
const filteredData = ref(treeData.value)
const filterNode = (value: string, data: TreeNode) => {
  if (!value) return true
  return data.label.toLowerCase().includes(value.toLowerCase())
}
const handleSearch = (searchText: string) => {
  treeRef.value?.filter(searchText)
}
const handleNodeClick = (data: TreeNode) => {
  if (data.path) {
    router.push(data.path)
  }
}
</script>
<style lang="less" scoped>
.tree-menu {
  height: 100%;
  background-color: #fff;
  :deep(.el-tree) {
    padding: 10px;
  }
  .custom-tree-node {
    display: flex;
    align-items: center;
    gap: 8px;
  }
}
</style>
src/layout/Header.vue
New file
@@ -0,0 +1,91 @@
<template>
  <div class="header-container">
    <div class="logo">
      <!-- <img src="../assets/vue.svg" alt="logo" /> -->
      <span>基于状态驱动的机构测试系统 </span>
    </div>
    <el-menu
      mode="horizontal"
      :default-active="activeIndex"
      class="header-menu"
      @select="handleSelect"
      router
    >
      <el-menu-item index="/">模型管理</el-menu-item>
      <el-menu-item index="/simulation-config">可视化仿真</el-menu-item>
      <el-menu-item index="/system/user">系统管理</el-menu-item>
    </el-menu>
  </div>
</template>
<script setup lang="ts">
import { ref } from "vue";
const activeIndex = ref("/");
const handleSelect = (key: string) => {
  console.log(key);
};
</script>
<style lang="less" scoped>
.header-container {
  display: flex;
  align-items: center;
  height: 100%;
  padding: 0 20px;
  .logo {
    display: flex;
    align-items: center;
    margin-right: 40px;
    img {
      height: 32px;
      margin-right: 10px;
    }
    span {
      font-size: 20px;
      font-weight: bold;
      color: #303133;
    }
  }
  .header-menu {
    flex: 1;
    border-bottom: none;
    background-color: transparent;
  }
  .header-right {
    margin-left: 20px;
    .user-info {
      display: flex;
      align-items: center;
      cursor: pointer;
      .el-avatar {
        margin-right: 8px;
      }
      span {
        color: #303133;
      }
    }
  }
}
:deep(.el-menu--horizontal) {
  border-bottom: none;
}
:deep(.el-menu-item) {
  color: #303133;
  &:hover {
    color: #303133;
  }
}
</style>
src/layout/main.vue
src/main.js
New file
@@ -0,0 +1,21 @@
import { createApp } from 'vue'
import App from './App.vue'
// 完整引入 Element Plus
import ElementPlus from 'element-plus'
import 'element-plus/dist/index.css'
import * as ElementPlusIconsVue from '@element-plus/icons-vue'
import './style.css'
import router from './router'
import './styles/global.less'
const app = createApp(App)
// 注册所有图标
for (const [key, component] of Object.entries(ElementPlusIconsVue)) {
  app.component(key, component)
}
// 使用 Element Plus
app.use(ElementPlus)
app.use(router)
app.mount('#app')
src/plugin/axios/index.ts
New file
@@ -0,0 +1,85 @@
import axios from 'axios'
import myConfig from '@/assets/js/config.js'
import toolClass from '@/assets/js/toolClass.js'
import router from '@/router'
// 创建 axios 实例
const service = axios.create({
  baseURL: myConfig.requestCtx,
  timeout: myConfig.requestTimeOut // 请求超时时间
})
// 请求拦截器
service.interceptors.request.use(
  (config) => {
    let token = localStorage.getItem(myConfig.tokenKey)
    if (token) config.headers['Authorization'] = `bearer ${token}`
    return config
  },
  (error) => {
    // 发送失败
    Promise.reject(error)
  }
)
// 响应拦截器
service.interceptors.response.use(
  (response) => {
    // dataAxios 是 axios 返回数据中的 data
    const dataAxios = response.data
    if (typeof dataAxios.data === 'boolean') {
      return dataAxios.data
    }
    if (response.config.responseType == 'blob') {
      return dataAxios
    }
    const { success } = dataAxios
    if (dataAxios.currentDate) {
      sessionStorage.currentDate = new Date(dataAxios.currentDate).getTime()
    }
    // 根据 code 进行判断
    if (success) {
      return dataAxios.data ? dataAxios.data : dataAxios
    } else {
      // 提示错误
    }
  },
  (error) => {
    if ((error.response && error.response.status == 401) || error.code == 'ERR_NETWORK') {
      localStorage.removeItem(myConfig.tokenKey)
      localStorage.removeItem('jesk-userInfo')
      localStorage.removeItem('alreadyElectronicBook')
      localStorage.removeItem('alreadyPaperBook')
      localStorage.removeItem('electronicBookList')
      localStorage.removeItem('paperBookList')
      sessionStorage.removeItem('cartNumber')
      // router.replace({
      //   path: '/home',
      //   query: {
      //     showLogin: '1'
      //   }
      // })
      const url = window.location.hash.slice(1)
      console.log(url, 'url')
      if (url.includes('showLogin=1')) {
        router.push(url)
      } else {
        // router.push(url)
        if (url.includes('?')) {
          console.log(url.includes('?'))
          router.push(url)
        } else {
          router.push(url + '?showLogin=1')
        }
      }
    } else {
      if (error.response && error.response.data && error.response.data.error) {
        console.error(error.response.data.error.msg)
      } else {
        console.error('请求发生错误')
      }
    }
    return Promise.reject(error)
  }
)
export default service
src/router/index.ts
New file
@@ -0,0 +1,43 @@
import { createRouter, createWebHistory } from 'vue-router'
const router = createRouter({
  history: createWebHistory(),
  routes: [
    {
      path: '/',
      redirect: '/mechanism'
    },
    {
      path: '/mechanism',
      name: 'mechanism',
      component: () => import('../views/model/Mechanism.vue')
    },
    {
      path: '/kinematic',
      name: 'kinematic',
      component: () => import('../views/model/Kinematic.vue')
    },
    {
      path: '/simulation-config',
      name: 'simulationConfig',
      component: () => import('../views/simulation/Config.vue')
    },
    {
      path: '/simulation-result',
      name: 'simulationResult',
      component: () => import('../views/simulation/Result.vue')
    },
    {
      path: '/system/user',
      name: 'systemUser',
      component: () => import('../views/system/User.vue')
    },
    {
      path: '/system/permission',
      name: 'systemPermission',
      component: () => import('../views/system/Permission.vue')
    }
  ]
})
export default router
src/style.css
New file
@@ -0,0 +1,117 @@
@import 'element-plus/dist/index.css';
:root {
  font-family: system-ui, Avenir, Helvetica, Arial, sans-serif;
  line-height: 1.5;
  font-weight: 400;
  color-scheme: light dark;
  color: rgba(255, 255, 255, 0.87);
  background-color: #242424;
  font-synthesis: none;
  text-rendering: optimizeLegibility;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}
a {
  font-weight: 500;
  color: #646cff;
  text-decoration: inherit;
}
a:hover {
  color: #535bf2;
}
html,
body {
  margin: 0;
  display: flex;
  place-items: center;
  width: 100%;
  height: 100%;
}
h1 {
  font-size: 3.2em;
  line-height: 1.1;
}
button {
  border-radius: 8px;
  border: 1px solid transparent;
  padding: 0.6em 1.2em;
  font-size: 1em;
  font-weight: 500;
  font-family: inherit;
  background-color: #1a1a1a;
  cursor: pointer;
  transition: border-color 0.25s;
}
button:hover {
  border-color: #646cff;
}
button:focus,
button:focus-visible {
  outline: 4px auto -webkit-focus-ring-color;
}
.card {
  padding: 2em;
}
#app {
  width: 100%;
  height: 100%;
  margin: 0 auto;
  text-align: center;
}
/* 引入 Element Plus 的基础样式 */
.common-layout {
  width: 100%;
  height: 100%;
}
.el-container {
  width: 100%;
  height: 100%;
}
.el-header {
  background-color: #fff;
  color: #333;
  line-height: 60px;
}
.el-aside {
  background-color: #D3DCE6;
  color: #333;
}
.el-main {
  background-color: #E9EEF3;
  color: #333;
}
.mb-4 {
  margin-bottom: 16px;
}
@media (prefers-color-scheme: light) {
  :root {
    color: #213547;
    background-color: #ffffff;
  }
  a:hover {
    color: #747bff;
  }
  button {
    background-color: #f9f9f9;
  }
}
src/styles/global.less
New file
@@ -0,0 +1,20 @@
:root {
  --primary-color: #409EFF;
  --success-color: #67C23A;
  --warning-color: #E6A23C;
  --danger-color: #F56C6C;
  --info-color: #909399;
}
html, body {
  margin: 0;
  padding: 0;
  height: 100%;
}
// 混入
.flex-center {
  display: flex;
  justify-content: center;
  align-items: center;
}
src/views/model/Kinematic.vue
New file
@@ -0,0 +1,14 @@
<template>
  <div class="kinematic">
    <h2>运动学模型</h2>
  </div>
</template>
<script setup lang="ts">
</script>
<style lang="less" scoped>
.kinematic {
  padding: 20px;
}
</style>
src/views/model/Mechanism.vue
New file
@@ -0,0 +1,14 @@
<template>
  <div class="mechanism">
    <h2>机构模型</h2>
  </div>
</template>
<script setup lang="ts">
</script>
<style lang="less" scoped>
.mechanism {
  padding: 20px;
}
</style>
src/views/simulation/Config.vue
New file
@@ -0,0 +1,14 @@
<template>
  <div class="simulation-config">
    <h2>仿真配置</h2>
  </div>
</template>
<script setup lang="ts">
</script>
<style lang="less" scoped>
.simulation-config {
  padding: 20px;
}
</style>
src/views/simulation/Result.vue
New file
@@ -0,0 +1,14 @@
<template>
  <div class="simulation-result">
    <h2>仿真结果</h2>
  </div>
</template>
<script setup lang="ts">
</script>
<style lang="less" scoped>
.simulation-result {
  padding: 20px;
}
</style>
src/views/system/Permission.vue
New file
@@ -0,0 +1,14 @@
<template>
  <div class="permission-manage">
    <h2>权限设置</h2>
  </div>
</template>
<script setup lang="ts">
</script>
<style lang="less" scoped>
.permission-manage {
  padding: 20px;
}
</style>
src/views/system/User.vue
New file
@@ -0,0 +1,14 @@
<template>
  <div class="user-manage">
    <h2>用户管理</h2>
  </div>
</template>
<script setup lang="ts">
</script>
<style lang="less" scoped>
.user-manage {
  padding: 20px;
}
</style>
vite.config.js
New file
@@ -0,0 +1,31 @@
import { fileURLToPath, URL } from 'node:url'
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
// https://vitejs.dev/config/
export default defineConfig({
  plugins: [
    vue(),
  ],
  base: "./",
  server: {
    host: '0.0.0.0'
  },
  resolve: {
    alias: {
      '@': fileURLToPath(new URL('./src', import.meta.url))
    }
  },
  css: {
    // 预处理器配置项
    preprocessorOptions: {
      less: {
        math: 'always'
      },
      scss: {
        additionalData: `@use "@/assets/element/index.scss" as *;`,
      }
    }
  }
})