feat: new
This commit is contained in:
@@ -17,11 +17,16 @@
|
|||||||
"@popperjs/core": "^2.11.8",
|
"@popperjs/core": "^2.11.8",
|
||||||
"@vueuse/core": "^10.6.1",
|
"@vueuse/core": "^10.6.1",
|
||||||
"axios": "^1.6.1",
|
"axios": "^1.6.1",
|
||||||
|
"localforage": "^1.10.0",
|
||||||
"pinia": "^2.1.7",
|
"pinia": "^2.1.7",
|
||||||
"pinia-plugin-persist": "^1.0.0",
|
"pinia-plugin-persist": "^1.0.0",
|
||||||
"svg-sprite-loader": "^6.0.11",
|
"svg-sprite-loader": "^6.0.11",
|
||||||
|
"three": "^0.160.0",
|
||||||
|
"three-css2drender": "^1.0.0",
|
||||||
"vue": "^3.3.8",
|
"vue": "^3.3.8",
|
||||||
"vue-router": "^4.2.5"
|
"vue-router": "^4.2.5",
|
||||||
|
"xlsx": "^0.18.5",
|
||||||
|
"zod": "^3.22.4"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@iconify-json/ep": "^1.1.12",
|
"@iconify-json/ep": "^1.1.12",
|
||||||
@@ -29,6 +34,7 @@
|
|||||||
"@tailwindcss/typography": "^0.5.10",
|
"@tailwindcss/typography": "^0.5.10",
|
||||||
"@testing-library/vue": "^8.0.0",
|
"@testing-library/vue": "^8.0.0",
|
||||||
"@types/node": "^20.9.0",
|
"@types/node": "^20.9.0",
|
||||||
|
"@types/three": "^0.160.0",
|
||||||
"@typescript-eslint/eslint-plugin": "^6.11.0",
|
"@typescript-eslint/eslint-plugin": "^6.11.0",
|
||||||
"@typescript-eslint/parser": "^6.11.0",
|
"@typescript-eslint/parser": "^6.11.0",
|
||||||
"@vitejs/plugin-vue": "^4.4.1",
|
"@vitejs/plugin-vue": "^4.4.1",
|
||||||
|
|||||||
135
pnpm-lock.yaml
generated
135
pnpm-lock.yaml
generated
@@ -17,6 +17,9 @@ dependencies:
|
|||||||
axios:
|
axios:
|
||||||
specifier: ^1.6.1
|
specifier: ^1.6.1
|
||||||
version: 1.6.1
|
version: 1.6.1
|
||||||
|
localforage:
|
||||||
|
specifier: ^1.10.0
|
||||||
|
version: 1.10.0
|
||||||
pinia:
|
pinia:
|
||||||
specifier: ^2.1.7
|
specifier: ^2.1.7
|
||||||
version: 2.1.7(typescript@5.2.2)(vue@3.3.8)
|
version: 2.1.7(typescript@5.2.2)(vue@3.3.8)
|
||||||
@@ -26,12 +29,24 @@ dependencies:
|
|||||||
svg-sprite-loader:
|
svg-sprite-loader:
|
||||||
specifier: ^6.0.11
|
specifier: ^6.0.11
|
||||||
version: 6.0.11
|
version: 6.0.11
|
||||||
|
three:
|
||||||
|
specifier: ^0.160.0
|
||||||
|
version: 0.160.0
|
||||||
|
three-css2drender:
|
||||||
|
specifier: ^1.0.0
|
||||||
|
version: 1.0.0(three@0.160.0)
|
||||||
vue:
|
vue:
|
||||||
specifier: ^3.3.8
|
specifier: ^3.3.8
|
||||||
version: 3.3.8(typescript@5.2.2)
|
version: 3.3.8(typescript@5.2.2)
|
||||||
vue-router:
|
vue-router:
|
||||||
specifier: ^4.2.5
|
specifier: ^4.2.5
|
||||||
version: 4.2.5(vue@3.3.8)
|
version: 4.2.5(vue@3.3.8)
|
||||||
|
xlsx:
|
||||||
|
specifier: ^0.18.5
|
||||||
|
version: 0.18.5
|
||||||
|
zod:
|
||||||
|
specifier: ^3.22.4
|
||||||
|
version: 3.22.4
|
||||||
|
|
||||||
devDependencies:
|
devDependencies:
|
||||||
'@iconify-json/ep':
|
'@iconify-json/ep':
|
||||||
@@ -49,6 +64,9 @@ devDependencies:
|
|||||||
'@types/node':
|
'@types/node':
|
||||||
specifier: ^20.9.0
|
specifier: ^20.9.0
|
||||||
version: 20.9.0
|
version: 20.9.0
|
||||||
|
'@types/three':
|
||||||
|
specifier: ^0.160.0
|
||||||
|
version: 0.160.0
|
||||||
'@typescript-eslint/eslint-plugin':
|
'@typescript-eslint/eslint-plugin':
|
||||||
specifier: ^6.11.0
|
specifier: ^6.11.0
|
||||||
version: 6.11.0(@typescript-eslint/parser@6.11.0)(eslint@8.53.0)(typescript@5.2.2)
|
version: 6.11.0(@typescript-eslint/parser@6.11.0)(eslint@8.53.0)(typescript@5.2.2)
|
||||||
@@ -710,15 +728,32 @@ packages:
|
|||||||
resolution: {integrity: sha512-+d+WYC1BxJ6yVOgUgzK8gWvp5qF8ssV5r4nsDcZWKRWcDQLQ619tvWAxJQYGgBrO1MnLJC7a5GtiYsAoQ47dJg==}
|
resolution: {integrity: sha512-+d+WYC1BxJ6yVOgUgzK8gWvp5qF8ssV5r4nsDcZWKRWcDQLQ619tvWAxJQYGgBrO1MnLJC7a5GtiYsAoQ47dJg==}
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
|
/@types/stats.js@0.17.3:
|
||||||
|
resolution: {integrity: sha512-pXNfAD3KHOdif9EQXZ9deK82HVNaXP5ZIF5RP2QG6OQFNTaY2YIetfrE9t528vEreGQvEPRDDc8muaoYeK0SxQ==}
|
||||||
|
dev: true
|
||||||
|
|
||||||
/@types/svgo@2.6.4:
|
/@types/svgo@2.6.4:
|
||||||
resolution: {integrity: sha512-l4cmyPEckf8moNYHdJ+4wkHvFxjyW6ulm9l4YGaOxeyBWPhBOT0gvni1InpFPdzx1dKf/2s62qGITwxNWnPQng==}
|
resolution: {integrity: sha512-l4cmyPEckf8moNYHdJ+4wkHvFxjyW6ulm9l4YGaOxeyBWPhBOT0gvni1InpFPdzx1dKf/2s62qGITwxNWnPQng==}
|
||||||
dependencies:
|
dependencies:
|
||||||
'@types/node': 20.9.0
|
'@types/node': 20.9.0
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
|
/@types/three@0.160.0:
|
||||||
|
resolution: {integrity: sha512-jWlbUBovicUKaOYxzgkLlhkiEQJkhCVvg4W2IYD2trqD2om3VK4DGLpHH5zQHNr7RweZK/5re/4IVhbhvxbV9w==}
|
||||||
|
dependencies:
|
||||||
|
'@types/stats.js': 0.17.3
|
||||||
|
'@types/webxr': 0.5.10
|
||||||
|
fflate: 0.6.10
|
||||||
|
meshoptimizer: 0.18.1
|
||||||
|
dev: true
|
||||||
|
|
||||||
/@types/web-bluetooth@0.0.20:
|
/@types/web-bluetooth@0.0.20:
|
||||||
resolution: {integrity: sha512-g9gZnnXVq7gM7v3tJCWV/qw7w+KeOlSHAhgF9RytFyifW6AF61hdT2ucrYhPq9hLs5JIryeupHV3qGk95dH9ow==}
|
resolution: {integrity: sha512-g9gZnnXVq7gM7v3tJCWV/qw7w+KeOlSHAhgF9RytFyifW6AF61hdT2ucrYhPq9hLs5JIryeupHV3qGk95dH9ow==}
|
||||||
|
|
||||||
|
/@types/webxr@0.5.10:
|
||||||
|
resolution: {integrity: sha512-n3u5sqXQJhf1CS68mw3Wf16FQ4cRPNBBwdYLFzq3UddiADOim1Pn3Y6PBdDilz1vOJF3ybLxJ8ZEDlLIzrOQZg==}
|
||||||
|
dev: true
|
||||||
|
|
||||||
/@typescript-eslint/eslint-plugin@6.11.0(@typescript-eslint/parser@6.11.0)(eslint@8.53.0)(typescript@5.2.2):
|
/@typescript-eslint/eslint-plugin@6.11.0(@typescript-eslint/parser@6.11.0)(eslint@8.53.0)(typescript@5.2.2):
|
||||||
resolution: {integrity: sha512-uXnpZDc4VRjY4iuypDBKzW1rz9T5YBBK0snMn8MaTSNd2kMlj50LnLBABELjJiOL5YHk7ZD8hbSpI9ubzqYI0w==}
|
resolution: {integrity: sha512-uXnpZDc4VRjY4iuypDBKzW1rz9T5YBBK0snMn8MaTSNd2kMlj50LnLBABELjJiOL5YHk7ZD8hbSpI9ubzqYI0w==}
|
||||||
engines: {node: ^16.0.0 || >=18.0.0}
|
engines: {node: ^16.0.0 || >=18.0.0}
|
||||||
@@ -1219,6 +1254,11 @@ packages:
|
|||||||
hasBin: true
|
hasBin: true
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
|
/adler-32@1.3.1:
|
||||||
|
resolution: {integrity: sha512-ynZ4w/nUUv5rrsR8UUGoe1VC9hZj6V5hU9Qw1HlMDJGEJw5S7TfTErWTjMys6M7vr0YWcPqs3qAr4ss0nDfP+A==}
|
||||||
|
engines: {node: '>=0.8'}
|
||||||
|
dev: false
|
||||||
|
|
||||||
/agent-base@6.0.2:
|
/agent-base@6.0.2:
|
||||||
resolution: {integrity: sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==}
|
resolution: {integrity: sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==}
|
||||||
engines: {node: '>= 6.0.0'}
|
engines: {node: '>= 6.0.0'}
|
||||||
@@ -1531,6 +1571,14 @@ packages:
|
|||||||
resolution: {integrity: sha512-kfte3Hym//51EdX4239i+Rmp20EsLIYGdPkERegTgU19hQWCRhsRFGKHTliUlsry53tv17K7n077Kqa0WJU4ng==}
|
resolution: {integrity: sha512-kfte3Hym//51EdX4239i+Rmp20EsLIYGdPkERegTgU19hQWCRhsRFGKHTliUlsry53tv17K7n077Kqa0WJU4ng==}
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
|
/cfb@1.2.2:
|
||||||
|
resolution: {integrity: sha512-KfdUZsSOw19/ObEWasvBP/Ac4reZvAGauZhs6S/gqNhXhI7cKwvlH7ulj+dOEYnca4bm4SGo8C1bTAQvnTjgQA==}
|
||||||
|
engines: {node: '>=0.8'}
|
||||||
|
dependencies:
|
||||||
|
adler-32: 1.3.1
|
||||||
|
crc-32: 1.2.2
|
||||||
|
dev: false
|
||||||
|
|
||||||
/chai@4.3.10:
|
/chai@4.3.10:
|
||||||
resolution: {integrity: sha512-0UXG04VuVbruMUYbJ6JctvH0YnC/4q3/AkT18q4NaITo91CUm0liMS9VqzT9vZhVQ/1eqPanMWjBM+Juhfb/9g==}
|
resolution: {integrity: sha512-0UXG04VuVbruMUYbJ6JctvH0YnC/4q3/AkT18q4NaITo91CUm0liMS9VqzT9vZhVQ/1eqPanMWjBM+Juhfb/9g==}
|
||||||
engines: {node: '>=4'}
|
engines: {node: '>=4'}
|
||||||
@@ -1619,6 +1667,11 @@ packages:
|
|||||||
resolution: {integrity: sha512-3Pe/CF1Nn94hyhIYpjtiLhdCoEoz0DqQ+988E9gmeEdQZlojxnOb74wctFyuwWQHzqyf9X7C7MG8juUpqBJT8w==}
|
resolution: {integrity: sha512-3Pe/CF1Nn94hyhIYpjtiLhdCoEoz0DqQ+988E9gmeEdQZlojxnOb74wctFyuwWQHzqyf9X7C7MG8juUpqBJT8w==}
|
||||||
engines: {node: '>=0.8'}
|
engines: {node: '>=0.8'}
|
||||||
|
|
||||||
|
/codepage@1.15.0:
|
||||||
|
resolution: {integrity: sha512-3g6NUTPd/YtuuGrhMnOMRjFc+LJw/bnMp3+0r/Wcz3IXUuCosKRJvMphm5+Q+bvTVGcJJuRvVLuYba+WojaFaA==}
|
||||||
|
engines: {node: '>=0.8'}
|
||||||
|
dev: false
|
||||||
|
|
||||||
/collection-visit@1.0.0:
|
/collection-visit@1.0.0:
|
||||||
resolution: {integrity: sha512-lNkKvzEeMBBjUGHZ+q6z9pSJla0KWAQPvtzhEV9+iGyQYG+pBpl7xKDhxoNSOZH2hhv0v5k0y2yAM4o4SjoSkw==}
|
resolution: {integrity: sha512-lNkKvzEeMBBjUGHZ+q6z9pSJla0KWAQPvtzhEV9+iGyQYG+pBpl7xKDhxoNSOZH2hhv0v5k0y2yAM4o4SjoSkw==}
|
||||||
engines: {node: '>=0.10.0'}
|
engines: {node: '>=0.10.0'}
|
||||||
@@ -1702,6 +1755,12 @@ packages:
|
|||||||
vary: 1.1.2
|
vary: 1.1.2
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
|
/crc-32@1.2.2:
|
||||||
|
resolution: {integrity: sha512-ROmzCKrTnOwybPcJApAA6WBWij23HVfGVNKqqrZpuyZOHqK2CwHSvpGuyt/UNNvaIjEd8X5IFGp4Mh+Ie1IHJQ==}
|
||||||
|
engines: {node: '>=0.8'}
|
||||||
|
hasBin: true
|
||||||
|
dev: false
|
||||||
|
|
||||||
/cross-spawn@7.0.3:
|
/cross-spawn@7.0.3:
|
||||||
resolution: {integrity: sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==}
|
resolution: {integrity: sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==}
|
||||||
engines: {node: '>= 8'}
|
engines: {node: '>= 8'}
|
||||||
@@ -2388,6 +2447,10 @@ packages:
|
|||||||
reusify: 1.0.4
|
reusify: 1.0.4
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
|
/fflate@0.6.10:
|
||||||
|
resolution: {integrity: sha512-IQrh3lEPM93wVCEczc9SaAOvkmcoQn/G8Bo1e8ZPlY3X3bnAxWaBdvTdvM1hP62iZp0BXWDy4vTAy4fF0+Dlpg==}
|
||||||
|
dev: true
|
||||||
|
|
||||||
/fflate@0.8.1:
|
/fflate@0.8.1:
|
||||||
resolution: {integrity: sha512-/exOvEuc+/iaUm105QIiOt4LpBdMTWsXxqR0HDF35vx3fmaKzw7354gTilCh5rkzEt8WYyG//ku3h3nRmd7CHQ==}
|
resolution: {integrity: sha512-/exOvEuc+/iaUm105QIiOt4LpBdMTWsXxqR0HDF35vx3fmaKzw7354gTilCh5rkzEt8WYyG//ku3h3nRmd7CHQ==}
|
||||||
dev: true
|
dev: true
|
||||||
@@ -2472,6 +2535,11 @@ packages:
|
|||||||
combined-stream: 1.0.8
|
combined-stream: 1.0.8
|
||||||
mime-types: 2.1.35
|
mime-types: 2.1.35
|
||||||
|
|
||||||
|
/frac@1.1.2:
|
||||||
|
resolution: {integrity: sha512-w/XBfkibaTl3YDqASwfDUqkna4Z2p9cFSr1aHDt0WoMTECnRfBOv2WArlZILlqgWlmdIlALXGpM2AOhEk5W3IA==}
|
||||||
|
engines: {node: '>=0.8'}
|
||||||
|
dev: false
|
||||||
|
|
||||||
/fraction.js@4.3.7:
|
/fraction.js@4.3.7:
|
||||||
resolution: {integrity: sha512-ZsDfxO51wGAXREY55a7la9LScWpwv9RxIrYABrlvOFBlH/ShPnrtsXeuUIfXKKOVicNxQ+o8JTbJvjS4M89yew==}
|
resolution: {integrity: sha512-ZsDfxO51wGAXREY55a7la9LScWpwv9RxIrYABrlvOFBlH/ShPnrtsXeuUIfXKKOVicNxQ+o8JTbJvjS4M89yew==}
|
||||||
dev: true
|
dev: true
|
||||||
@@ -2797,6 +2865,10 @@ packages:
|
|||||||
engines: {node: '>=0.10.0'}
|
engines: {node: '>=0.10.0'}
|
||||||
hasBin: true
|
hasBin: true
|
||||||
|
|
||||||
|
/immediate@3.0.6:
|
||||||
|
resolution: {integrity: sha512-XXOFtyqDjNDAQxVfYxuF7g9Il/IbWmmlQg2MYKOH8ExIT1qg6xc4zyS3HaEEATgs1btfzxq15ciUiY7gjSXRGQ==}
|
||||||
|
dev: false
|
||||||
|
|
||||||
/immutable@4.3.4:
|
/immutable@4.3.4:
|
||||||
resolution: {integrity: sha512-fsXeu4J4i6WNWSikpI88v/PcVflZz+6kMhUfIwc5SY+poQRPnaf5V7qds6SUyUN3cVxEzuCab7QIoLOQ+DQ1wA==}
|
resolution: {integrity: sha512-fsXeu4J4i6WNWSikpI88v/PcVflZz+6kMhUfIwc5SY+poQRPnaf5V7qds6SUyUN3cVxEzuCab7QIoLOQ+DQ1wA==}
|
||||||
dev: true
|
dev: true
|
||||||
@@ -3263,6 +3335,12 @@ packages:
|
|||||||
type-check: 0.4.0
|
type-check: 0.4.0
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
|
/lie@3.1.1:
|
||||||
|
resolution: {integrity: sha512-RiNhHysUjhrDQntfYSfY4MU24coXXdEOgw9WGcKHNeEwffDYbF//u87M1EWaMGzuFoSbqW0C9C6lEEhDOAswfw==}
|
||||||
|
dependencies:
|
||||||
|
immediate: 3.0.6
|
||||||
|
dev: false
|
||||||
|
|
||||||
/lilconfig@2.1.0:
|
/lilconfig@2.1.0:
|
||||||
resolution: {integrity: sha512-utWOt/GHzuUxnLKxB6dk81RoOeoNeHgbrXiuGk4yyF5qlRz+iIVWu56E2fqGHFrXz0QNUhLB/8nKqvRH66JKGQ==}
|
resolution: {integrity: sha512-utWOt/GHzuUxnLKxB6dk81RoOeoNeHgbrXiuGk4yyF5qlRz+iIVWu56E2fqGHFrXz0QNUhLB/8nKqvRH66JKGQ==}
|
||||||
engines: {node: '>=10'}
|
engines: {node: '>=10'}
|
||||||
@@ -3298,6 +3376,12 @@ packages:
|
|||||||
pkg-types: 1.0.3
|
pkg-types: 1.0.3
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
|
/localforage@1.10.0:
|
||||||
|
resolution: {integrity: sha512-14/H1aX7hzBBmmh7sGPd+AOMkkIrHM3Z1PAyGgZigA1H1p5O5ANnMyWzvpAETtG68/dC4pC0ncy3+PPGzXZHPg==}
|
||||||
|
dependencies:
|
||||||
|
lie: 3.1.1
|
||||||
|
dev: false
|
||||||
|
|
||||||
/locate-path@6.0.0:
|
/locate-path@6.0.0:
|
||||||
resolution: {integrity: sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==}
|
resolution: {integrity: sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==}
|
||||||
engines: {node: '>=10'}
|
engines: {node: '>=10'}
|
||||||
@@ -3381,6 +3465,10 @@ packages:
|
|||||||
engines: {node: '>= 8'}
|
engines: {node: '>= 8'}
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
|
/meshoptimizer@0.18.1:
|
||||||
|
resolution: {integrity: sha512-ZhoIoL7TNV4s5B6+rx5mC//fw8/POGyNxS/DZyCJeiZ12ScLfVwRE/GfsxwiTkMYYD5DmK2/JXnEVXqL4rF+Sw==}
|
||||||
|
dev: true
|
||||||
|
|
||||||
/micromatch@3.1.0:
|
/micromatch@3.1.0:
|
||||||
resolution: {integrity: sha512-3StSelAE+hnRvMs8IdVW7Uhk8CVed5tp+kLLGlBP6WiRAXS21GPGu/Nat4WNPXj2Eoc24B02SaeoyozPMfj0/g==}
|
resolution: {integrity: sha512-3StSelAE+hnRvMs8IdVW7Uhk8CVed5tp+kLLGlBP6WiRAXS21GPGu/Nat4WNPXj2Eoc24B02SaeoyozPMfj0/g==}
|
||||||
engines: {node: '>=0.10.0'}
|
engines: {node: '>=0.10.0'}
|
||||||
@@ -4405,6 +4493,13 @@ packages:
|
|||||||
dependencies:
|
dependencies:
|
||||||
extend-shallow: 3.0.2
|
extend-shallow: 3.0.2
|
||||||
|
|
||||||
|
/ssf@0.11.2:
|
||||||
|
resolution: {integrity: sha512-+idbmIXoYET47hH+d7dfm2epdOMUDjqcB4648sTZ+t2JwoyBFL/insLfB/racrDmsKB3diwsDA696pZMieAC5g==}
|
||||||
|
engines: {node: '>=0.8'}
|
||||||
|
dependencies:
|
||||||
|
frac: 1.1.2
|
||||||
|
dev: false
|
||||||
|
|
||||||
/stable@0.1.8:
|
/stable@0.1.8:
|
||||||
resolution: {integrity: sha512-ji9qxRnOVfcuLDySj9qzhGSEFVobyt1kIOSkj1qZzYLzq7Tos/oUUWvotUPQLlrsidqsK6tBH89Bc9kL5zHA6w==}
|
resolution: {integrity: sha512-ji9qxRnOVfcuLDySj9qzhGSEFVobyt1kIOSkj1qZzYLzq7Tos/oUUWvotUPQLlrsidqsK6tBH89Bc9kL5zHA6w==}
|
||||||
deprecated: 'Modern JS already guarantees Array#sort() is a stable sort, so this library is deprecated. See the compatibility table on MDN: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort#browser_compatibility'
|
deprecated: 'Modern JS already guarantees Array#sort() is a stable sort, so this library is deprecated. See the compatibility table on MDN: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort#browser_compatibility'
|
||||||
@@ -4701,6 +4796,18 @@ packages:
|
|||||||
any-promise: 1.3.0
|
any-promise: 1.3.0
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
|
/three-css2drender@1.0.0(three@0.160.0):
|
||||||
|
resolution: {integrity: sha512-redDCSBDvgxiJIm6EDT8WO5WJTVg5gUEy/vjtAgJa/zX4peEUnZ8K+mXo6v94EudbnuI5h48/hQo9NExf04ENg==}
|
||||||
|
peerDependencies:
|
||||||
|
three: '>= 0.91'
|
||||||
|
dependencies:
|
||||||
|
three: 0.160.0
|
||||||
|
dev: false
|
||||||
|
|
||||||
|
/three@0.160.0:
|
||||||
|
resolution: {integrity: sha512-DLU8lc0zNIPkM7rH5/e1Ks1Z8tWCGRq6g8mPowdDJpw1CFBJMU7UoJjC6PefXW7z//SSl0b2+GCw14LB+uDhng==}
|
||||||
|
dev: false
|
||||||
|
|
||||||
/tinybench@2.5.1:
|
/tinybench@2.5.1:
|
||||||
resolution: {integrity: sha512-65NKvSuAVDP/n4CqH+a9w2kTlLReS9vhsAP06MWx+/89nMinJyB2icyl58RIcqCmIggpojIGeuJGhjU1aGMBSg==}
|
resolution: {integrity: sha512-65NKvSuAVDP/n4CqH+a9w2kTlLReS9vhsAP06MWx+/89nMinJyB2icyl58RIcqCmIggpojIGeuJGhjU1aGMBSg==}
|
||||||
dev: true
|
dev: true
|
||||||
@@ -5434,6 +5541,16 @@ packages:
|
|||||||
stackback: 0.0.2
|
stackback: 0.0.2
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
|
/wmf@1.0.2:
|
||||||
|
resolution: {integrity: sha512-/p9K7bEh0Dj6WbXg4JG0xvLQmIadrner1bi45VMJTfnbVHsc7yIajZyoSoK60/dtVBs12Fm6WkUI5/3WAVsNMw==}
|
||||||
|
engines: {node: '>=0.8'}
|
||||||
|
dev: false
|
||||||
|
|
||||||
|
/word@0.3.0:
|
||||||
|
resolution: {integrity: sha512-OELeY0Q61OXpdUfTp+oweA/vtLVg5VDOXh+3he3PNzLGG/y0oylSOC1xRVj0+l4vQ3tj/bB1HVHv1ocXkQceFA==}
|
||||||
|
engines: {node: '>=0.8'}
|
||||||
|
dev: false
|
||||||
|
|
||||||
/wrap-ansi@7.0.0:
|
/wrap-ansi@7.0.0:
|
||||||
resolution: {integrity: sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==}
|
resolution: {integrity: sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==}
|
||||||
engines: {node: '>=10'}
|
engines: {node: '>=10'}
|
||||||
@@ -5469,6 +5586,20 @@ packages:
|
|||||||
optional: true
|
optional: true
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
|
/xlsx@0.18.5:
|
||||||
|
resolution: {integrity: sha512-dmg3LCjBPHZnQp5/F/+nnTa+miPJxUXB6vtk42YjBBKayDNagxGEeIdWApkYPOf3Z3pm3k62Knjzp7lMeTEtFQ==}
|
||||||
|
engines: {node: '>=0.8'}
|
||||||
|
hasBin: true
|
||||||
|
dependencies:
|
||||||
|
adler-32: 1.3.1
|
||||||
|
cfb: 1.2.2
|
||||||
|
codepage: 1.15.0
|
||||||
|
crc-32: 1.2.2
|
||||||
|
ssf: 0.11.2
|
||||||
|
wmf: 1.0.2
|
||||||
|
word: 0.3.0
|
||||||
|
dev: false
|
||||||
|
|
||||||
/xml-name-validator@4.0.0:
|
/xml-name-validator@4.0.0:
|
||||||
resolution: {integrity: sha512-ICP2e+jsHvAj2E2lIHxa5tjXRlKDJo4IdvPvCXbXQGdzSfmSpNVyIKMvoZHjDY9DP0zV17iI85o90vRFXNccRw==}
|
resolution: {integrity: sha512-ICP2e+jsHvAj2E2lIHxa5tjXRlKDJo4IdvPvCXbXQGdzSfmSpNVyIKMvoZHjDY9DP0zV17iI85o90vRFXNccRw==}
|
||||||
engines: {node: '>=12'}
|
engines: {node: '>=12'}
|
||||||
@@ -5519,3 +5650,7 @@ packages:
|
|||||||
resolution: {integrity: sha512-9bnSc/HEW2uRy67wc+T8UwauLuPJVn28jb+GtJY16iiKWyvmYJRXVT4UamsAEGQfPohgr2q4Tq0sQbQlxTfi1g==}
|
resolution: {integrity: sha512-9bnSc/HEW2uRy67wc+T8UwauLuPJVn28jb+GtJY16iiKWyvmYJRXVT4UamsAEGQfPohgr2q4Tq0sQbQlxTfi1g==}
|
||||||
engines: {node: '>=12.20'}
|
engines: {node: '>=12.20'}
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
|
/zod@3.22.4:
|
||||||
|
resolution: {integrity: sha512-iC+8Io04lddc+mVqQ9AZ7OQ2MrUKGN+oIQyq1vemgt46jwCwLfhq7/pwnBnNXXXZb8VTVLKwp9EDkx+ryxIWmg==}
|
||||||
|
dev: false
|
||||||
|
|||||||
@@ -5,5 +5,4 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<style scoped lang="scss">
|
<style scoped lang="scss">
|
||||||
@import "@/style/global.module.scss";
|
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
2644
src/assets/model.obj
Normal file
2644
src/assets/model.obj
Normal file
File diff suppressed because it is too large
Load Diff
1
src/components.d.ts
vendored
1
src/components.d.ts
vendored
@@ -7,6 +7,7 @@ export {}
|
|||||||
|
|
||||||
declare module 'vue' {
|
declare module 'vue' {
|
||||||
export interface GlobalComponents {
|
export interface GlobalComponents {
|
||||||
|
DaiysuiTable: typeof import('./components/DaiysuiTable/index.vue')['default']
|
||||||
HelloWorld: typeof import('./components/HelloWorld.vue')['default']
|
HelloWorld: typeof import('./components/HelloWorld.vue')['default']
|
||||||
RouterLink: typeof import('vue-router')['RouterLink']
|
RouterLink: typeof import('vue-router')['RouterLink']
|
||||||
RouterView: typeof import('vue-router')['RouterView']
|
RouterView: typeof import('vue-router')['RouterView']
|
||||||
|
|||||||
64
src/components/DaiysuiTable/index.vue
Normal file
64
src/components/DaiysuiTable/index.vue
Normal file
@@ -0,0 +1,64 @@
|
|||||||
|
import { mapActions } from 'pinia';
|
||||||
|
<script setup lang='ts'>
|
||||||
|
import { computed } from 'vue';
|
||||||
|
const props= defineProps({
|
||||||
|
data: {
|
||||||
|
type: Array,
|
||||||
|
default: [] as any[]
|
||||||
|
},
|
||||||
|
tableColumns: {
|
||||||
|
type: Array,
|
||||||
|
default: [] as any[]
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
const dataColumns=computed(()=>{
|
||||||
|
// 不带有actions的列
|
||||||
|
const columns= props.tableColumns.filter(item=>!item.actions)
|
||||||
|
|
||||||
|
return columns
|
||||||
|
})
|
||||||
|
|
||||||
|
const actionsColumns=computed(()=>{
|
||||||
|
// 带有actions的列
|
||||||
|
const columns= props.tableColumns.filter(item=>item.actions)
|
||||||
|
|
||||||
|
return columns
|
||||||
|
})
|
||||||
|
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<div class="overflow-x-auto">
|
||||||
|
<table class="table">
|
||||||
|
<!-- head -->
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th></th>
|
||||||
|
<th v-for="(item, index) in dataColumns" :key="index">{{ item.label }}</th>
|
||||||
|
<th v-for="(item, index) in actionsColumns" :key="index">操作</th>
|
||||||
|
<th></th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
<!-- row -->
|
||||||
|
<tr class="hover" v-for="item in data" :key="item.id">
|
||||||
|
<th>{{ item.id }}</th>
|
||||||
|
<td v-for="(column,index) in dataColumns" :key="index">
|
||||||
|
<span v-if="column.formatValue">{{ column.formatValue(item) }}</span>
|
||||||
|
<span v-else>{{ item[column.props] }}</span>
|
||||||
|
</td>
|
||||||
|
<!-- action -->
|
||||||
|
<td v-for="(column,index) in actionsColumns" :key="index" class="flex gap-2">
|
||||||
|
<button class="btn btn-xs" v-for="action in column.actions" :key="action.name" :class="action.type" @click="action.onClick(item)">{{ action.label}}</button>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
<!-- foot -->
|
||||||
|
|
||||||
|
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<style lang='scss' scoped></style>
|
||||||
1
src/icons/down.svg
Normal file
1
src/icons/down.svg
Normal file
@@ -0,0 +1 @@
|
|||||||
|
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1704385528419" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="4272" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><path d="M512 128c212 0 384 172 384 384s-172 384-384 384-384-172-384-384 172-384 384-384m0-64C264.8 64 64 264.8 64 512s200.8 448 448 448 448-200.8 448-448S759.2 64 512 64z m226.4 322.4L512 613.6 285.6 386.4 240 432l226.4 226.4L512 704l45.6-45.6L784 432l-45.6-45.6z" p-id="4273"></path></svg>
|
||||||
|
After Width: | Height: | Size: 615 B |
1
src/icons/up.svg
Normal file
1
src/icons/up.svg
Normal file
@@ -0,0 +1 @@
|
|||||||
|
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1704385525165" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="4133" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><path d="M512 128c212 0 384 172 384 384s-172 384-384 384-384-172-384-384 172-384 384-384m0-64C264.8 64 64 264.8 64 512s200.8 448 448 448 448-200.8 448-448S759.2 64 512 64z m272 530.4L557.6 368 512 322.4 466.4 368 240 594.4l45.6 45.6L512 413.6 738.4 640l45.6-45.6z" p-id="4134"></path></svg>
|
||||||
|
After Width: | Height: | Size: 614 B |
@@ -1,19 +1,19 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import Header from './Header/index.vue';
|
// import Header from './Header/index.vue';
|
||||||
import Footer from './Footer/index.vue';
|
// import Footer from './Footer/index.vue';
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<div class="w-screen">
|
<div class="w-screen">
|
||||||
<header class="shadow-2xl head-container h-14">
|
<!-- <header class="shadow-2xl head-container h-14">
|
||||||
<Header></Header>
|
<Header></Header>
|
||||||
</header>
|
</header> -->
|
||||||
<main class="main-container w-screen box-content min-h-[calc(100vh-10rem)]">
|
<main class="box-content w-screen h-screen main-container">
|
||||||
<router-view class="main-container-content"></router-view>
|
<router-view class="main-container-content"></router-view>
|
||||||
</main>
|
</main>
|
||||||
<footer class="w-screen footer-container">
|
<!-- <footer class="w-screen footer-container">
|
||||||
<Footer></Footer>
|
<Footer></Footer>
|
||||||
</footer>
|
</footer> -->
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<style scoped lang="scss">
|
<style scoped lang="scss">
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
import { createApp } from 'vue';
|
import { createApp } from 'vue';
|
||||||
import './style.css';
|
import './style.css';
|
||||||
|
import './style/style.scss'
|
||||||
|
import * as THREE from 'three';
|
||||||
import App from './App.vue';
|
import App from './App.vue';
|
||||||
|
|
||||||
const app = createApp(App);
|
const app = createApp(App);
|
||||||
@@ -15,5 +16,7 @@ import { createPinia } from 'pinia';
|
|||||||
import piniaPluginPersist from 'pinia-plugin-persist';
|
import piniaPluginPersist from 'pinia-plugin-persist';
|
||||||
const pinia = createPinia();
|
const pinia = createPinia();
|
||||||
pinia.use(piniaPluginPersist);
|
pinia.use(piniaPluginPersist);
|
||||||
|
|
||||||
|
app.config.globalProperties.$THREE = THREE; //挂载到原型
|
||||||
app.component('svg-icon', svgIcon);
|
app.component('svg-icon', svgIcon);
|
||||||
app.use(router).use(pinia).mount('#app');
|
app.use(router).use(pinia).mount('#app');
|
||||||
|
|||||||
@@ -1,6 +1,97 @@
|
|||||||
import { createRouter, createWebHistory } from 'vue-router';
|
import { createRouter, createWebHistory } from 'vue-router';
|
||||||
import Layout from '@/layout/index.vue';
|
import Layout from '@/layout/index.vue';
|
||||||
import Home from '@/views/Home/index.vue';
|
import Home from '@/views/Home/index.vue';
|
||||||
|
export const configRoutes={
|
||||||
|
path: '/config',
|
||||||
|
name: 'Config',
|
||||||
|
component: () => import('@/views/Config/index.vue'),
|
||||||
|
children: [
|
||||||
|
{
|
||||||
|
path: '',
|
||||||
|
redirect: '/config/person',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: '/config/person',
|
||||||
|
name: 'PersonConfig',
|
||||||
|
component: () => import('@/views/Config/Person/PersonConfig.vue'),
|
||||||
|
meta: {
|
||||||
|
title: '人员配置',
|
||||||
|
icon: 'person',
|
||||||
|
},
|
||||||
|
children:[
|
||||||
|
{
|
||||||
|
path:'',
|
||||||
|
redirect: '/config/person/all',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path:'/config/person/all',
|
||||||
|
name:'AllPersonConfig',
|
||||||
|
component:()=>import('@/views/Config/Person/PersonAll.vue'),
|
||||||
|
meta:{
|
||||||
|
title:'所有人员',
|
||||||
|
icon:'all'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path:'/config/person/already',
|
||||||
|
name:'AlreadyPerson',
|
||||||
|
component:()=>import('@/views/Config/Person/PersonAlready.vue'),
|
||||||
|
meta:{
|
||||||
|
title:'已领取人员',
|
||||||
|
icon:'already'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
// {
|
||||||
|
// path:'other',
|
||||||
|
// name:'OtherPersonConfig',
|
||||||
|
// component:()=>import('@/views/Config/Person/OtherPersonConfig.vue'),
|
||||||
|
// meta:{
|
||||||
|
// title:'其他配置',
|
||||||
|
// icon:'other'
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: '/config/prize',
|
||||||
|
name: 'PrizeConfig',
|
||||||
|
component: () => import('@/views/Config/Prize/PrizeConfig.vue'),
|
||||||
|
meta:{
|
||||||
|
title: '奖品配置',
|
||||||
|
icon: 'prize'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path:'/config/global',
|
||||||
|
name:'GlobalConfig',
|
||||||
|
redirect: '/config/global/all',
|
||||||
|
meta:{
|
||||||
|
title:'全局配置',
|
||||||
|
icon:'global'
|
||||||
|
},
|
||||||
|
children:[
|
||||||
|
{
|
||||||
|
path:'/config/global/face',
|
||||||
|
name:'FaceConfig',
|
||||||
|
component:()=>import('@/views/Config/Global/FaceConfig.vue'),
|
||||||
|
meta:{
|
||||||
|
title:'界面配置',
|
||||||
|
icon:'face'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path:'/config/global/image',
|
||||||
|
name:'ImageConfig',
|
||||||
|
component:()=>import('@/views/Config/Global/ImageConfig.vue'),
|
||||||
|
meta:{
|
||||||
|
title:'图片配置',
|
||||||
|
icon:'image'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
const routes = [
|
const routes = [
|
||||||
{
|
{
|
||||||
path: '/',
|
path: '/',
|
||||||
@@ -12,11 +103,7 @@ const routes = [
|
|||||||
name: 'Home',
|
name: 'Home',
|
||||||
component: Home,
|
component: Home,
|
||||||
},
|
},
|
||||||
{
|
configRoutes,
|
||||||
path: '/guide',
|
|
||||||
name: 'Guide',
|
|
||||||
component: () => import('@/views/Guide/index.vue'),
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
path: '/doc',
|
path: '/doc',
|
||||||
name: 'Doc',
|
name: 'Doc',
|
||||||
|
|||||||
@@ -1,7 +1,10 @@
|
|||||||
import { useUserStore } from './user';
|
import { useUserStore } from './user';
|
||||||
|
import {usePersonConfig} from './personConfig';
|
||||||
|
import { usePrizeConfig } from './prizeConfig';
|
||||||
export default function useStore() {
|
export default function useStore() {
|
||||||
return {
|
return {
|
||||||
user: useUserStore(),
|
user: useUserStore(),
|
||||||
|
personConfig:usePersonConfig(),
|
||||||
|
prizeConfig:usePrizeConfig()
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
102
src/store/personConfig.ts
Normal file
102
src/store/personConfig.ts
Normal file
@@ -0,0 +1,102 @@
|
|||||||
|
import { defineStore } from 'pinia';
|
||||||
|
import { IPersonConfig } from '@/types/personConfig';
|
||||||
|
export const usePersonConfig = defineStore('person', {
|
||||||
|
state() {
|
||||||
|
return {
|
||||||
|
personConfig:{
|
||||||
|
alreadyPersonList:[] as IPersonConfig[],
|
||||||
|
notPersonList:[] as IPersonConfig[],
|
||||||
|
tableRowCount:12,
|
||||||
|
showField:[] as any[]
|
||||||
|
}
|
||||||
|
};
|
||||||
|
},
|
||||||
|
getters: {
|
||||||
|
// 获取全部配置
|
||||||
|
getPersonConfig(state) {
|
||||||
|
return state.personConfig;
|
||||||
|
},
|
||||||
|
// 获取已中奖人员名单
|
||||||
|
getAlreadyPersonList(state) {
|
||||||
|
return state.personConfig.alreadyPersonList;
|
||||||
|
},
|
||||||
|
// 获取未中奖人员名单
|
||||||
|
getNotPersonList(state) {
|
||||||
|
return state.personConfig.notPersonList;
|
||||||
|
},
|
||||||
|
// 获取table列数
|
||||||
|
getTableRowCount(state) {
|
||||||
|
return state.personConfig.tableRowCount;
|
||||||
|
},
|
||||||
|
// 获取要展示那些字段
|
||||||
|
getShowField(state) {
|
||||||
|
return state.personConfig.showField;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
actions: {
|
||||||
|
// 添加未中奖人员
|
||||||
|
addNotPersonList(personList: IPersonConfig[]) {
|
||||||
|
if(personList.length<=0){
|
||||||
|
return
|
||||||
|
}
|
||||||
|
personList.forEach((item: IPersonConfig) => {
|
||||||
|
this.personConfig.notPersonList.push(item);
|
||||||
|
});
|
||||||
|
},
|
||||||
|
// 添加已中奖人员
|
||||||
|
addAlreadyPersonList(personList: IPersonConfig[]) {
|
||||||
|
if(personList.length<=0){
|
||||||
|
return
|
||||||
|
}
|
||||||
|
personList.forEach((item: IPersonConfig) => {
|
||||||
|
this.personConfig.alreadyPersonList.push(item);
|
||||||
|
this.personConfig.notPersonList = this.personConfig.notPersonList.filter((item: IPersonConfig) => item.id!== item.id);
|
||||||
|
});
|
||||||
|
},
|
||||||
|
// 删除所有人员
|
||||||
|
deleteAllPerson() {
|
||||||
|
this.personConfig.alreadyPersonList = [];
|
||||||
|
this.personConfig.notPersonList = [];
|
||||||
|
},
|
||||||
|
// 设置table列数
|
||||||
|
setTableRowCount(tableRowCount: number) {
|
||||||
|
this.personConfig.tableRowCount = tableRowCount;
|
||||||
|
},
|
||||||
|
// 设置要展示那些字段
|
||||||
|
setShowFields(showField: any[]) {
|
||||||
|
this.personConfig.showField = showField;
|
||||||
|
},
|
||||||
|
// 重置所有人员
|
||||||
|
resetPerson() {
|
||||||
|
this.personConfig.alreadyPersonList = [];
|
||||||
|
this.personConfig.notPersonList = [];
|
||||||
|
},
|
||||||
|
// 重置已中奖人员
|
||||||
|
resetAlreadyPerson() {
|
||||||
|
// 把已中奖人员合并到未中奖人员,要验证是否已存在
|
||||||
|
if(this.personConfig.alreadyPersonList.length>0){
|
||||||
|
this.personConfig.notPersonList = this.personConfig.notPersonList.concat(this.personConfig.alreadyPersonList);
|
||||||
|
this.personConfig.alreadyPersonList = [];
|
||||||
|
}
|
||||||
|
},
|
||||||
|
// 重置所有配置
|
||||||
|
reset() {
|
||||||
|
this.personConfig = {
|
||||||
|
alreadyPersonList:[] as IPersonConfig[],
|
||||||
|
notPersonList:[] as IPersonConfig[],
|
||||||
|
tableRowCount:12,
|
||||||
|
showField:[] as string[]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
},
|
||||||
|
persist: {
|
||||||
|
enabled: true,
|
||||||
|
strategies: [
|
||||||
|
{
|
||||||
|
// 如果要存储在localStorage中
|
||||||
|
storage: localStorage,
|
||||||
|
key: 'personConfig',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
});
|
||||||
59
src/store/prizeConfig.ts
Normal file
59
src/store/prizeConfig.ts
Normal file
@@ -0,0 +1,59 @@
|
|||||||
|
import { defineStore } from 'pinia';
|
||||||
|
import { IPrizeConfig } from '@/types/prizeConfig';
|
||||||
|
export const usePrizeConfig = defineStore('prize', {
|
||||||
|
state() {
|
||||||
|
return {
|
||||||
|
prizeConfig:{
|
||||||
|
prizeList:[] as IPrizeConfig[],
|
||||||
|
}
|
||||||
|
};
|
||||||
|
},
|
||||||
|
getters: {
|
||||||
|
// 获取全部配置
|
||||||
|
getPrizeConfig(state) {
|
||||||
|
return state.prizeConfig.prizeList;
|
||||||
|
},
|
||||||
|
// 根据id获取配置
|
||||||
|
getPrizeConfigById(state) {
|
||||||
|
return (id: number|string) => {
|
||||||
|
return state.prizeConfig.prizeList.find(item => item.id === id);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
},
|
||||||
|
actions: {
|
||||||
|
// 设置奖项
|
||||||
|
setPrizeConfig(prizeList:IPrizeConfig[]) {
|
||||||
|
this.prizeConfig.prizeList = prizeList;
|
||||||
|
},
|
||||||
|
// 添加奖项
|
||||||
|
addPrizeConfig(prizeConfigItem: IPrizeConfig) {
|
||||||
|
this.prizeConfig.prizeList.push(prizeConfigItem);
|
||||||
|
},
|
||||||
|
// 删除奖项
|
||||||
|
deletePrizeConfig(prizeConfigItemId: number|string) {
|
||||||
|
this.prizeConfig.prizeList = this.prizeConfig.prizeList.filter(item => item.id!== prizeConfigItemId);
|
||||||
|
},
|
||||||
|
// 更新奖项数据
|
||||||
|
updatePrizeConfig(prizeConfigItem: IPrizeConfig) {
|
||||||
|
const index = this.prizeConfig.prizeList.findIndex(item => item.id === prizeConfigItem.id);
|
||||||
|
this.prizeConfig.prizeList[index] = prizeConfigItem;
|
||||||
|
},
|
||||||
|
// 重置所有配置
|
||||||
|
reset() {
|
||||||
|
this.prizeConfig = {
|
||||||
|
prizeList:[] as IPrizeConfig[],
|
||||||
|
}
|
||||||
|
},
|
||||||
|
},
|
||||||
|
persist: {
|
||||||
|
enabled: true,
|
||||||
|
strategies: [
|
||||||
|
{
|
||||||
|
// 如果要存储在localStorage中
|
||||||
|
storage: localStorage,
|
||||||
|
key: 'personConfig',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
});
|
||||||
@@ -1,22 +0,0 @@
|
|||||||
$theme-color: #2e1f78;
|
|
||||||
$important-color: #02e5f6;
|
|
||||||
$font-color: #fbfbfb;
|
|
||||||
$light-color: #fd5913;
|
|
||||||
$normal-color: #15115d;
|
|
||||||
$dark-card-color: #fbfbfb;
|
|
||||||
|
|
||||||
$blue_theme: (
|
|
||||||
theme-bg-color: $theme-color,
|
|
||||||
font-color: $font-color,
|
|
||||||
font-color-second: darken($font-color, 20%),
|
|
||||||
light-bg-color: $light-color,
|
|
||||||
normal-color: $normal-color,
|
|
||||||
header-bg-color: lighten($theme-color, 10%),
|
|
||||||
header-bg-color-hover: lighten($theme-color, 20%),
|
|
||||||
shawdow-color: darken($theme-color, 5%),
|
|
||||||
shawdow-color-hover: darken($theme-color, 15%),
|
|
||||||
border-color: lighten($theme-color, 20%),
|
|
||||||
important-color: lighten($important-color, 20%),
|
|
||||||
important-bg-color: transparentize($important-color, 0.9),
|
|
||||||
dark-card-color: $dark-card-color,
|
|
||||||
);
|
|
||||||
@@ -1,22 +0,0 @@
|
|||||||
$theme-color: #1e1f25;
|
|
||||||
$important-color: #ff864d;
|
|
||||||
$font-color: #fbfbfb;
|
|
||||||
$light-color: #00e6f6;
|
|
||||||
$normal-color: #183561;
|
|
||||||
$dark-card-color: #fbfbfb;
|
|
||||||
|
|
||||||
$dark_theme: (
|
|
||||||
theme-bg-color: $theme-color,
|
|
||||||
font-color: $font-color,
|
|
||||||
font-color-second: darken($font-color, 20%),
|
|
||||||
light-bg-color: $light-color,
|
|
||||||
normal-color: $normal-color,
|
|
||||||
header-bg-color: lighten($theme-color, 10%),
|
|
||||||
header-bg-color-hover: lighten($theme-color, 20%),
|
|
||||||
shawdow-color: darken($theme-color, 5%),
|
|
||||||
shawdow-color-hover: darken($theme-color, 15%),
|
|
||||||
border-color: lighten($theme-color, 20%),
|
|
||||||
important-color: lighten($important-color, 20%),
|
|
||||||
important-bg-color: transparentize($important-color, 0.9),
|
|
||||||
dark-card-color: $dark-card-color,
|
|
||||||
);
|
|
||||||
@@ -1,22 +0,0 @@
|
|||||||
$theme-color: #fbfbfb;
|
|
||||||
$important-color: #6a47bb;
|
|
||||||
$font-color: #030303;
|
|
||||||
$light-color: #409eff;
|
|
||||||
$normal-color: #fbfbfb;
|
|
||||||
$dark-card-color: #fbfbfb;
|
|
||||||
|
|
||||||
$default: (
|
|
||||||
theme-bg-color: $theme-color,
|
|
||||||
font-color: $font-color,
|
|
||||||
font-color-second: darken($font-color, 20%),
|
|
||||||
light-bg-color: $light-color,
|
|
||||||
normal-color: $normal-color,
|
|
||||||
header-bg-color: lighten($theme-color, 10%),
|
|
||||||
header-bg-color-hover: lighten($theme-color, 20%),
|
|
||||||
shawdow-color: darken($theme-color, 5%),
|
|
||||||
shawdow-color-hover: darken($theme-color, 15%),
|
|
||||||
border-color: lighten($theme-color, 20%),
|
|
||||||
important-color: lighten($important-color, 20%),
|
|
||||||
important-bg-color: transparentize($important-color, 0.9),
|
|
||||||
dark-card-color: $dark-card-color,
|
|
||||||
);
|
|
||||||
@@ -1,22 +0,0 @@
|
|||||||
$theme-color: #0a142e;
|
|
||||||
$important-color: #8c5ff6;
|
|
||||||
$font-color: #fbfbfb;
|
|
||||||
$light-color: #c678fd;
|
|
||||||
$normal-color: #0a142e;
|
|
||||||
$dark-card-color: #fbfbfb;
|
|
||||||
|
|
||||||
$purple_theme: (
|
|
||||||
theme-bg-color: $theme-color,
|
|
||||||
font-color: $font-color,
|
|
||||||
font-color-second: darken($font-color, 20%),
|
|
||||||
light-bg-color: $light-color,
|
|
||||||
normal-color: $normal-color,
|
|
||||||
header-bg-color: lighten($theme-color, 10%),
|
|
||||||
header-bg-color-hover: lighten($theme-color, 20%),
|
|
||||||
shawdow-color: darken($theme-color, 5%),
|
|
||||||
shawdow-color-hover: darken($theme-color, 15%),
|
|
||||||
border-color: lighten($theme-color, 20%),
|
|
||||||
important-color: lighten($important-color, 20%),
|
|
||||||
important-bg-color: transparentize($important-color, 0.9),
|
|
||||||
dark-card-color: $dark-card-color,
|
|
||||||
);
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
import './global.scss';
|
|
||||||
@@ -1,14 +0,0 @@
|
|||||||
:root {
|
|
||||||
font-family: Inter, Avenir, Helvetica, Arial, sans-serif;
|
|
||||||
font-size: 16px;
|
|
||||||
line-height: 24px;
|
|
||||||
font-weight: 400;
|
|
||||||
font-synthesis: none;
|
|
||||||
text-rendering: optimizeLegibility;
|
|
||||||
-webkit-font-smoothing: antialiased;
|
|
||||||
-moz-osx-font-smoothing: grayscale;
|
|
||||||
-webkit-text-size-adjust: 100%;
|
|
||||||
}
|
|
||||||
body {
|
|
||||||
// background: $theme-bg-color;
|
|
||||||
}
|
|
||||||
@@ -1,5 +1,4 @@
|
|||||||
// global.scss
|
// global.scss
|
||||||
@import "./theme/index.scss";
|
|
||||||
// variables.scss
|
// variables.scss
|
||||||
$primary-color: #fe4e5e;
|
$primary-color: #fe4e5e;
|
||||||
$background-color: #fefefe;
|
$background-color: #fefefe;
|
||||||
@@ -9,3 +8,5 @@ $padding: 124px;
|
|||||||
// backgroundColor: $background-color;
|
// backgroundColor: $background-color;
|
||||||
// padding: $padding;
|
// padding: $padding;
|
||||||
// }
|
// }
|
||||||
|
|
||||||
|
/*end*/
|
||||||
|
|||||||
@@ -1,50 +0,0 @@
|
|||||||
@import "./default.scss"; //默认主题颜色
|
|
||||||
@import "./dark_theme.scss"; // 红色主题颜色
|
|
||||||
@import "./blue_theme.scss"; // 灰色主题颜色
|
|
||||||
@import "./purple_theme.scss"; // 灰色主题颜色
|
|
||||||
//生成对应元素的主题样式代码
|
|
||||||
//主题参数
|
|
||||||
$themes: (
|
|
||||||
default: $default,
|
|
||||||
blue_theme: $blue_theme,
|
|
||||||
dark_theme: $dark_theme,
|
|
||||||
purple_theme: $purple_theme,
|
|
||||||
);
|
|
||||||
// 生成body的主题样式
|
|
||||||
@mixin themeify {
|
|
||||||
@each $themes-key, $themes-map in $themes {
|
|
||||||
$themes-map: $themes-map !global;
|
|
||||||
&[data-theme="#{$themes-key}"] {
|
|
||||||
@content;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// 生成子元素样式
|
|
||||||
@mixin themeChildify {
|
|
||||||
@each $themes-key, $themes-map in $themes {
|
|
||||||
$themes-map: $themes-map !global;
|
|
||||||
[data-theme="#{$themes-key}"] & {
|
|
||||||
@content;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// 获取主题对应的theme-color
|
|
||||||
@function getThemeColor($key) {
|
|
||||||
$currentTheme: map-get($themes, $key);
|
|
||||||
@return map-get($currentTheme, "theme-bg-color");
|
|
||||||
}
|
|
||||||
@function themed($key) {
|
|
||||||
@if map-get($themes-map, $key) {
|
|
||||||
@return map-get($themes-map, $key);
|
|
||||||
} @else {
|
|
||||||
@return $key;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// 随机数颜色
|
|
||||||
@function themedRandom($key) {
|
|
||||||
@if map-get($themes-map, $key) {
|
|
||||||
@return map-get($themes-map, $key);
|
|
||||||
} @else {
|
|
||||||
@return $key;
|
|
||||||
}
|
|
||||||
} ;
|
|
||||||
41
src/style/style.scss
Normal file
41
src/style/style.scss
Normal file
@@ -0,0 +1,41 @@
|
|||||||
|
.element-card {
|
||||||
|
width: 140px;
|
||||||
|
height: 200px;
|
||||||
|
cursor: default;
|
||||||
|
text-align: center;
|
||||||
|
border: 1px solid rgba(127, 255, 255, 0.25);
|
||||||
|
box-shadow: 0 0 12px rgba(0, 255, 255, 0.5);
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
border: 1px solid rgba(127, 255, 255, 0.75);
|
||||||
|
box-shadow: 0 0 12px rgba(0, 255, 255, 0.75);
|
||||||
|
}
|
||||||
|
|
||||||
|
.card-id {
|
||||||
|
position: absolute;
|
||||||
|
top: 20px;
|
||||||
|
right: 20px;
|
||||||
|
font-size: 12px;
|
||||||
|
color: rgba(127, 255, 255, 0.75);
|
||||||
|
}
|
||||||
|
|
||||||
|
.card-name {
|
||||||
|
position: absolute;
|
||||||
|
top: 40px;
|
||||||
|
left: 0px;
|
||||||
|
right: 0;
|
||||||
|
font-size: 30px;
|
||||||
|
font-weight: bold;
|
||||||
|
color: rgba(255, 255, 255, 0.75);
|
||||||
|
text-shadow: 0 0 10px rgba(0, 255, 255, 0.95);
|
||||||
|
}
|
||||||
|
|
||||||
|
.card-detail {
|
||||||
|
position: absolute;
|
||||||
|
left: 0;
|
||||||
|
right: 0;
|
||||||
|
bottom: 15px;
|
||||||
|
font-size: 12px;
|
||||||
|
color: rgba(127, 255, 255, 0.75);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,22 +0,0 @@
|
|||||||
$theme-color: #2e1f78;
|
|
||||||
$important-color: #02e5f6;
|
|
||||||
$font-color: #fbfbfb;
|
|
||||||
$light-color: #fd5913;
|
|
||||||
$normal-color: #15115d;
|
|
||||||
$dark-card-color: #fbfbfb;
|
|
||||||
|
|
||||||
$blue_theme: (
|
|
||||||
theme-bg-color: $theme-color,
|
|
||||||
font-color: $font-color,
|
|
||||||
font-color-second: darken($font-color, 20%),
|
|
||||||
light-bg-color: $light-color,
|
|
||||||
normal-color: $normal-color,
|
|
||||||
header-bg-color: lighten($theme-color, 10%),
|
|
||||||
header-bg-color-hover: lighten($theme-color, 20%),
|
|
||||||
shawdow-color: darken($theme-color, 5%),
|
|
||||||
shawdow-color-hover: darken($theme-color, 15%),
|
|
||||||
border-color: lighten($theme-color, 20%),
|
|
||||||
important-color: lighten($important-color, 20%),
|
|
||||||
important-bg-color: transparentize($important-color, 0.9),
|
|
||||||
dark-card-color: $dark-card-color,
|
|
||||||
);
|
|
||||||
@@ -1,22 +0,0 @@
|
|||||||
$theme-color: #1e1f25;
|
|
||||||
$important-color: #ff864d;
|
|
||||||
$font-color: #fbfbfb;
|
|
||||||
$light-color: #00e6f6;
|
|
||||||
$normal-color: #183561;
|
|
||||||
$dark-card-color: #fbfbfb;
|
|
||||||
|
|
||||||
$dark_theme: (
|
|
||||||
theme-bg-color: $theme-color,
|
|
||||||
font-color: $font-color,
|
|
||||||
font-color-second: darken($font-color, 20%),
|
|
||||||
light-bg-color: $light-color,
|
|
||||||
normal-color: $normal-color,
|
|
||||||
header-bg-color: lighten($theme-color, 10%),
|
|
||||||
header-bg-color-hover: lighten($theme-color, 20%),
|
|
||||||
shawdow-color: darken($theme-color, 5%),
|
|
||||||
shawdow-color-hover: darken($theme-color, 15%),
|
|
||||||
border-color: lighten($theme-color, 20%),
|
|
||||||
important-color: lighten($important-color, 20%),
|
|
||||||
important-bg-color: transparentize($important-color, 0.9),
|
|
||||||
dark-card-color: $dark-card-color,
|
|
||||||
);
|
|
||||||
@@ -1,22 +0,0 @@
|
|||||||
$theme-color: #fbfbfb;
|
|
||||||
$important-color: #6a47bb;
|
|
||||||
$font-color: #030303;
|
|
||||||
$light-color: #409eff;
|
|
||||||
$normal-color: #fbfbfb;
|
|
||||||
$dark-card-color: #fbfbfb;
|
|
||||||
|
|
||||||
$default: (
|
|
||||||
theme-bg-color: $theme-color,
|
|
||||||
font-color: $font-color,
|
|
||||||
font-color-second: darken($font-color, 20%),
|
|
||||||
light-bg-color: $light-color,
|
|
||||||
normal-color: $normal-color,
|
|
||||||
header-bg-color: lighten($theme-color, 10%),
|
|
||||||
header-bg-color-hover: lighten($theme-color, 20%),
|
|
||||||
shawdow-color: darken($theme-color, 5%),
|
|
||||||
shawdow-color-hover: darken($theme-color, 15%),
|
|
||||||
border-color: lighten($theme-color, 20%),
|
|
||||||
important-color: lighten($important-color, 20%),
|
|
||||||
important-bg-color: transparentize($important-color, 0.9),
|
|
||||||
dark-card-color: $dark-card-color,
|
|
||||||
);
|
|
||||||
@@ -1,22 +0,0 @@
|
|||||||
$theme-color: #0a142e;
|
|
||||||
$important-color: #8c5ff6;
|
|
||||||
$font-color: #fbfbfb;
|
|
||||||
$light-color: #c678fd;
|
|
||||||
$normal-color: #0a142e;
|
|
||||||
$dark-card-color: #fbfbfb;
|
|
||||||
|
|
||||||
$purple_theme: (
|
|
||||||
theme-bg-color: $theme-color,
|
|
||||||
font-color: $font-color,
|
|
||||||
font-color-second: darken($font-color, 20%),
|
|
||||||
light-bg-color: $light-color,
|
|
||||||
normal-color: $normal-color,
|
|
||||||
header-bg-color: lighten($theme-color, 10%),
|
|
||||||
header-bg-color-hover: lighten($theme-color, 20%),
|
|
||||||
shawdow-color: darken($theme-color, 5%),
|
|
||||||
shawdow-color-hover: darken($theme-color, 15%),
|
|
||||||
border-color: lighten($theme-color, 20%),
|
|
||||||
important-color: lighten($important-color, 20%),
|
|
||||||
important-bg-color: transparentize($important-color, 0.9),
|
|
||||||
dark-card-color: $dark-card-color,
|
|
||||||
);
|
|
||||||
@@ -1,50 +0,0 @@
|
|||||||
@import "./default.scss"; //默认主题颜色
|
|
||||||
@import "./dark_theme.scss"; // 红色主题颜色
|
|
||||||
@import "./blue_theme.scss"; // 灰色主题颜色
|
|
||||||
@import "./purple_theme.scss"; // 灰色主题颜色
|
|
||||||
//生成对应元素的主题样式代码
|
|
||||||
//主题参数
|
|
||||||
$themes: (
|
|
||||||
default: $default,
|
|
||||||
blue_theme: $blue_theme,
|
|
||||||
dark_theme: $dark_theme,
|
|
||||||
purple_theme: $purple_theme,
|
|
||||||
);
|
|
||||||
// 生成body的主题样式
|
|
||||||
@mixin themeify {
|
|
||||||
@each $themes-key, $themes-map in $themes {
|
|
||||||
$themes-map: $themes-map !global;
|
|
||||||
&[data-theme="#{$themes-key}"] {
|
|
||||||
@content;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// 生成子元素样式
|
|
||||||
@mixin themeChildify {
|
|
||||||
@each $themes-key, $themes-map in $themes {
|
|
||||||
$themes-map: $themes-map !global;
|
|
||||||
[data-theme="#{$themes-key}"] & {
|
|
||||||
@content;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// 获取主题对应的theme-color
|
|
||||||
@function getThemeColor($key) {
|
|
||||||
$currentTheme: map-get($themes, $key);
|
|
||||||
@return map-get($currentTheme, "theme-bg-color");
|
|
||||||
}
|
|
||||||
@function themed($key) {
|
|
||||||
@if map-get($themes-map, $key) {
|
|
||||||
@return map-get($themes-map, $key);
|
|
||||||
} @else {
|
|
||||||
@return $key;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// 随机数颜色
|
|
||||||
@function themedRandom($key) {
|
|
||||||
@if map-get($themes-map, $key) {
|
|
||||||
@return map-get($themes-map, $key);
|
|
||||||
} @else {
|
|
||||||
@return $key;
|
|
||||||
}
|
|
||||||
} ;
|
|
||||||
10
src/types/personConfig.ts
Normal file
10
src/types/personConfig.ts
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
export interface IPersonConfig {
|
||||||
|
id: number;
|
||||||
|
uid: string;
|
||||||
|
name: string;
|
||||||
|
department:string;
|
||||||
|
other:string;
|
||||||
|
isWin:boolean;
|
||||||
|
x:number;
|
||||||
|
y:number
|
||||||
|
}
|
||||||
10
src/types/prizeConfig.ts
Normal file
10
src/types/prizeConfig.ts
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
export interface IPrizeConfig {
|
||||||
|
id: number|string;
|
||||||
|
name:string;
|
||||||
|
sort:number;
|
||||||
|
isAll:boolean;
|
||||||
|
count:number;
|
||||||
|
picture:string[];
|
||||||
|
desc:string;
|
||||||
|
isShow:boolean;
|
||||||
|
}
|
||||||
19
src/utils/file.ts
Normal file
19
src/utils/file.ts
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
export const readFile = (file: any) => {
|
||||||
|
return new Promise(resolve => {
|
||||||
|
const reader = new FileReader()
|
||||||
|
reader.readAsBinaryString(file)
|
||||||
|
reader.onload = (ev: any) => {
|
||||||
|
resolve(ev.target.result)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
export const readImage = (file: any) => {
|
||||||
|
return new Promise(resolve => {
|
||||||
|
const reader = new FileReader()
|
||||||
|
reader.readAsDataURL(file)
|
||||||
|
reader.onload = (ev: any) => {
|
||||||
|
resolve({dataUrl:ev.target.result,fileName:file.name})
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
0
src/utils/indexDB.ts
Normal file
0
src/utils/indexDB.ts
Normal file
10
src/utils/store.ts
Normal file
10
src/utils/store.ts
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
// 提取有哪些字段
|
||||||
|
export const extractFields = (data: any) => {
|
||||||
|
const item=data[0];
|
||||||
|
// 排除id x y,其他都加入数组
|
||||||
|
const keys = Object.keys(item).filter(key => key!== 'id' && key!== 'x' && key!== 'y');
|
||||||
|
if(keys.length>0){
|
||||||
|
// 返回数组key value
|
||||||
|
return keys.map(key => ({label:key,value:true}));
|
||||||
|
}
|
||||||
|
};
|
||||||
90
src/views/Config/Global/FaceConfig.vue
Normal file
90
src/views/Config/Global/FaceConfig.vue
Normal file
@@ -0,0 +1,90 @@
|
|||||||
|
<script setup lang='ts'>
|
||||||
|
import { ref, watch } from 'vue'
|
||||||
|
import useStore from '@/store'
|
||||||
|
import zod from 'zod';
|
||||||
|
|
||||||
|
const personConfig = useStore().personConfig
|
||||||
|
const { getTableRowCount: tableRowCount, getShowField} = personConfig
|
||||||
|
|
||||||
|
const formData = ref({
|
||||||
|
rowCount: tableRowCount,
|
||||||
|
showField: getShowField
|
||||||
|
})
|
||||||
|
const formErr = ref({
|
||||||
|
rowCount: '',
|
||||||
|
})
|
||||||
|
|
||||||
|
const schema = zod.object({
|
||||||
|
rowCount: zod.number({
|
||||||
|
required_error: '必填项',
|
||||||
|
invalid_type_error: '必须填入数字',
|
||||||
|
})
|
||||||
|
.min(1, '最小为1')
|
||||||
|
.max(100, '最大为100')
|
||||||
|
// 格式化
|
||||||
|
|
||||||
|
|
||||||
|
})
|
||||||
|
type ValidatePayload = zod.infer<typeof schema>
|
||||||
|
const payload: ValidatePayload = {
|
||||||
|
rowCount: formData.value.rowCount,
|
||||||
|
}
|
||||||
|
const parseSchema = (props: ValidatePayload) => {
|
||||||
|
return schema.parseAsync(props)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const handleChangeShowFields = (fieldItem: any) => {
|
||||||
|
formData.value.showField.map((item)=>{
|
||||||
|
if(item.label===fieldItem.label){
|
||||||
|
item.value=!item.value
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
watch(() => formData.value.rowCount, () => {
|
||||||
|
payload.rowCount = formData.value.rowCount
|
||||||
|
parseSchema(payload).then(res => {
|
||||||
|
console.log('code line-40 \n\r😀 res:\n\r', res);
|
||||||
|
if(res.rowCount){
|
||||||
|
personConfig.setTableRowCount(res.rowCount)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.catch(err => {
|
||||||
|
formErr.value.rowCount = err.issues[0].message
|
||||||
|
})
|
||||||
|
})
|
||||||
|
watch(() => formData.value.showField, () => {
|
||||||
|
personConfig.setShowFields(formData.value.showField)
|
||||||
|
},{deep:true})
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
<label class="w-full max-w-xs mb-10 form-control">
|
||||||
|
<div class="label">
|
||||||
|
<span class="label-text">列数</span>
|
||||||
|
</div>
|
||||||
|
<input type="number" v-model="formData.rowCount" placeholder="Type here"
|
||||||
|
class="w-full max-w-xs input input-bordered" />
|
||||||
|
<div class="help">
|
||||||
|
<span class="text-sm text-red-400 help-text" v-if="formErr.rowCount">
|
||||||
|
{{ formErr.rowCount }}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</label>
|
||||||
|
<label class="w-full max-w-xs form-control">
|
||||||
|
<div class="label">
|
||||||
|
<span class="label-text">展示字段</span>
|
||||||
|
</div>
|
||||||
|
<ul class="flex gap-6 pl-0">
|
||||||
|
<li v-for="item in formData.showField" :key="item" class="flex items-center gap-1">
|
||||||
|
<input type="checkbox" :checked="item.value" class="border-solid checkbox checkbox-primary border-1" @change="handleChangeShowFields(item)"/>
|
||||||
|
<span class="label-text">{{ item.label }}</span>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<style lang='scss' scoped></style>
|
||||||
91
src/views/Config/Global/ImageConfig.vue
Normal file
91
src/views/Config/Global/ImageConfig.vue
Normal file
@@ -0,0 +1,91 @@
|
|||||||
|
<script setup lang='ts'>
|
||||||
|
import { ref, onMounted, watch } from 'vue'
|
||||||
|
import { readImage } from '@/utils/file'
|
||||||
|
import localforage from 'localforage'
|
||||||
|
|
||||||
|
const limitType = ref('image/*')
|
||||||
|
const imgList = ref<any>([])
|
||||||
|
const imgUploadToast = ref(0) //0是不显示,1是成功,2是失败,3是不是图片
|
||||||
|
const imageDbStore = localforage.createInstance({
|
||||||
|
name: 'imgStore'
|
||||||
|
})
|
||||||
|
const handleFileChange = async (e: any) => {
|
||||||
|
const isImage= /image*/.test(e.target.files[0].type)
|
||||||
|
if (!isImage) {
|
||||||
|
imgUploadToast.value = 3
|
||||||
|
|
||||||
|
return
|
||||||
|
}
|
||||||
|
let { dataUrl, fileName } = await readImage(e.target.files[0])
|
||||||
|
imageDbStore.setItem(new Date().getTime().toString() + '+' + fileName, dataUrl)
|
||||||
|
.then(() => {
|
||||||
|
imgUploadToast.value = 1
|
||||||
|
})
|
||||||
|
.catch(() => {
|
||||||
|
imgUploadToast.value = 2
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
const getImageDbStore =async () => {
|
||||||
|
const keys =await imageDbStore.keys()
|
||||||
|
if(keys.length>0){
|
||||||
|
imageDbStore.iterate((value, key) => {
|
||||||
|
imgList.value.push({
|
||||||
|
key,
|
||||||
|
value
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
getImageDbStore()
|
||||||
|
})
|
||||||
|
watch(() => imgUploadToast.value, (val) => {
|
||||||
|
if (val !== 0) {
|
||||||
|
setTimeout(() => {
|
||||||
|
imgUploadToast.value = 0
|
||||||
|
}, 2000)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<div class="toast toast-top toast-end">
|
||||||
|
<div class="alert alert-error" v-if="imgUploadToast == 2">
|
||||||
|
<span>上传失败</span>
|
||||||
|
</div>
|
||||||
|
<div class="alert alert-success" v-if="imgUploadToast == 1">
|
||||||
|
<span>上传成功</span>
|
||||||
|
</div>
|
||||||
|
<div class="alert alert-error" v-if="imgUploadToast == 3">
|
||||||
|
<span>不是图片</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<div class="">
|
||||||
|
<label for="explore">
|
||||||
|
<input type="file" class="" id="explore" style="display: none" @change="handleFileChange"
|
||||||
|
:accept="limitType" />
|
||||||
|
<span class="btn btn-primary btn-sm">上传图片</span>
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
<ul>
|
||||||
|
<li v-for="item in imgList" :key="item">
|
||||||
|
<div class="flex items-center gap-3">
|
||||||
|
<div class="avatar">
|
||||||
|
<div class="mask mask-squircle w-12 h-12">
|
||||||
|
<img :src="item.value" alt="Avatar Tailwind CSS Component" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<div class="font-bold">{{ item.key.split('+')[1] }}</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<style lang='scss' scoped></style>
|
||||||
121
src/views/Config/Person/PersonAll.vue
Normal file
121
src/views/Config/Person/PersonAll.vue
Normal file
@@ -0,0 +1,121 @@
|
|||||||
|
<!-- eslint-disable vue/no-parsing-error -->
|
||||||
|
<script setup lang='ts'>
|
||||||
|
import { ref } from 'vue';
|
||||||
|
import useStore from '@/store'
|
||||||
|
import * as XLSX from 'xlsx'
|
||||||
|
import { readFile } from '@/utils/file'
|
||||||
|
import DaiysuiTable from '@/components/DaiysuiTable/index.vue'
|
||||||
|
|
||||||
|
import {extractFields} from '@/utils/store'
|
||||||
|
|
||||||
|
const personConfig = useStore().personConfig
|
||||||
|
|
||||||
|
const { getAlreadyPersonList: alreadyPersonList, getNotPersonList: notPersonList ,getTableRowCount:rowCount} = personConfig
|
||||||
|
const limitType = '.xlsx,.xls'
|
||||||
|
const excelData = ref<any[]>([])
|
||||||
|
const personList = ref<any[]>(
|
||||||
|
notPersonList.concat(alreadyPersonList)
|
||||||
|
)
|
||||||
|
const handleFileChange = async (e: any) => {
|
||||||
|
let dataBinary = await readFile(e.target.files[0])
|
||||||
|
let workBook = XLSX.read(dataBinary, { type: 'binary', cellDates: true })
|
||||||
|
let workSheet = workBook.Sheets[workBook.SheetNames[0]]
|
||||||
|
excelData.value = XLSX.utils.sheet_to_json(workSheet)
|
||||||
|
personList.value = filterData(excelData.value)
|
||||||
|
|
||||||
|
const keys=extractFields(personList.value)
|
||||||
|
personConfig.resetPerson()
|
||||||
|
personConfig.setShowFields(keys)
|
||||||
|
personConfig.addNotPersonList(personList.value)
|
||||||
|
}
|
||||||
|
|
||||||
|
const filterData = (tableData: any[]) => {
|
||||||
|
const dataLength = tableData.length
|
||||||
|
let j = 0;
|
||||||
|
for (let i = 0; i < dataLength; i++) {
|
||||||
|
if (i % rowCount === 0) {
|
||||||
|
j++;
|
||||||
|
}
|
||||||
|
tableData[i].x = i % rowCount + 1;
|
||||||
|
tableData[i].y = j;
|
||||||
|
tableData[i].id = i;
|
||||||
|
// 是否中奖
|
||||||
|
tableData[i].isWin = false
|
||||||
|
}
|
||||||
|
|
||||||
|
return personList.value = tableData
|
||||||
|
}
|
||||||
|
const deleteAll = () => {
|
||||||
|
personConfig.deleteAllPerson()
|
||||||
|
personList.value = notPersonList.concat(alreadyPersonList)
|
||||||
|
}
|
||||||
|
|
||||||
|
const tableColumns = [
|
||||||
|
{
|
||||||
|
label: '编号',
|
||||||
|
props: 'uid',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: '姓名',
|
||||||
|
props: 'name',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: '部门',
|
||||||
|
props: 'department',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: '职位',
|
||||||
|
props: 'other',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label:'是否已中奖',
|
||||||
|
props: 'isWin',
|
||||||
|
formatValue(row: any) {
|
||||||
|
return row.isWin? '是' : '否'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: '操作',
|
||||||
|
actions: [
|
||||||
|
{
|
||||||
|
label: '编辑',
|
||||||
|
type: 'btn-info',
|
||||||
|
onClick: (row: any) => {
|
||||||
|
console.log('编辑:', row)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: '删除',
|
||||||
|
type: 'btn-error',
|
||||||
|
onClick: (row: any) => {
|
||||||
|
console.log('删除:', row)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
]
|
||||||
|
},
|
||||||
|
]
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<div class="overflow-y-auto">
|
||||||
|
<div class="flex justify-center gap-3">
|
||||||
|
<button class="btn btn-error btn-sm" @click="deleteAll">全部删除</button>
|
||||||
|
<div class="">
|
||||||
|
<label for="explore">
|
||||||
|
<input type="file"
|
||||||
|
class=""
|
||||||
|
id="explore"
|
||||||
|
style="display: none"
|
||||||
|
@change="handleFileChange" :accept="limitType" />
|
||||||
|
<span class="btn btn-primary btn-sm">上传文件</span>
|
||||||
|
</label>
|
||||||
|
<!-- <button class="btn btn-primary btn-sm">上传excel</button> -->
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<DaiysuiTable :tableColumns="tableColumns" :data="personList"></DaiysuiTable>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<style lang='scss' scoped></style>
|
||||||
70
src/views/Config/Person/PersonAlready.vue
Normal file
70
src/views/Config/Person/PersonAlready.vue
Normal file
@@ -0,0 +1,70 @@
|
|||||||
|
<!-- eslint-disable vue/no-parsing-error -->
|
||||||
|
<script setup lang='ts'>
|
||||||
|
import { ref } from 'vue';
|
||||||
|
import useStore from '@/store'
|
||||||
|
import DaiysuiTable from '@/components/DaiysuiTable/index.vue'
|
||||||
|
|
||||||
|
const personConfig = useStore().personConfig
|
||||||
|
|
||||||
|
const { getAlreadyPersonList: alreadyPersonList } = personConfig
|
||||||
|
const personList = ref<any[]>(
|
||||||
|
alreadyPersonList
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
const deleteAll = () => {
|
||||||
|
personConfig.deleteAllPerson()
|
||||||
|
personList.value = alreadyPersonList
|
||||||
|
}
|
||||||
|
|
||||||
|
const tableColumns = [
|
||||||
|
{
|
||||||
|
label: '编号',
|
||||||
|
props: 'uid',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: '姓名',
|
||||||
|
props: 'name',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: '部门',
|
||||||
|
props: 'department',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: '职位',
|
||||||
|
props: 'other',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: '操作',
|
||||||
|
actions: [
|
||||||
|
{
|
||||||
|
label: '编辑',
|
||||||
|
type: 'btn-info',
|
||||||
|
onClick: (row: any) => {
|
||||||
|
console.log('编辑:', row)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: '删除',
|
||||||
|
type: 'btn-error',
|
||||||
|
onClick: (row: any) => {
|
||||||
|
console.log('删除:', row)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
]
|
||||||
|
},
|
||||||
|
]
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<div class="overflow-y-auto">
|
||||||
|
<div class="flex justify-center gap-3">
|
||||||
|
<button class="btn btn-error btn-sm" @click="deleteAll">全部删除</button>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
<DaiysuiTable :tableColumns="tableColumns" :data="personList"></DaiysuiTable>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<style lang='scss' scoped></style>
|
||||||
13
src/views/Config/Person/PersonConfig.vue
Normal file
13
src/views/Config/Person/PersonConfig.vue
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
<script setup lang='ts'>
|
||||||
|
|
||||||
|
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<router-view></router-view>
|
||||||
|
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<style lang='scss' scoped>
|
||||||
|
|
||||||
|
</style>
|
||||||
114
src/views/Config/Prize/PrizeConfig.vue
Normal file
114
src/views/Config/Prize/PrizeConfig.vue
Normal file
@@ -0,0 +1,114 @@
|
|||||||
|
<script setup lang='ts'>
|
||||||
|
import { ref, onMounted,watch } from 'vue'
|
||||||
|
import useStore from '@/store'
|
||||||
|
|
||||||
|
import localforage from 'localforage'
|
||||||
|
import { IPrizeConfig } from '@/types/prizeConfig';
|
||||||
|
|
||||||
|
const imageDbStore = localforage.createInstance({
|
||||||
|
name: 'imgStore'
|
||||||
|
})
|
||||||
|
const prizeConfig = useStore().prizeConfig
|
||||||
|
const { getPrizeConfig } = prizeConfig
|
||||||
|
const prizeList = ref(getPrizeConfig)
|
||||||
|
const imgList = ref<any[]>([])
|
||||||
|
const addPrize = () => {
|
||||||
|
const defaultPrizeCOnfig: IPrizeConfig = {
|
||||||
|
id: new Date().getTime().toString(),
|
||||||
|
name: '奖项',
|
||||||
|
sort: 0,
|
||||||
|
isAll: false,
|
||||||
|
count: 1,
|
||||||
|
picture: [''],
|
||||||
|
desc: '',
|
||||||
|
isShow: true
|
||||||
|
}
|
||||||
|
prizeConfig.addPrizeConfig(defaultPrizeCOnfig)
|
||||||
|
}
|
||||||
|
|
||||||
|
const getImageDbStore = async () => {
|
||||||
|
const keys = await imageDbStore.keys()
|
||||||
|
if (keys.length > 0) {
|
||||||
|
imageDbStore.iterate((value, key) => {
|
||||||
|
imgList.value.push({
|
||||||
|
key,
|
||||||
|
value
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const sort = (item:any,isUp:number) => {
|
||||||
|
const itemIndex=prizeList.value.indexOf(item)
|
||||||
|
if(isUp==1){
|
||||||
|
prizeList.value.splice(itemIndex,1)
|
||||||
|
prizeList.value.splice(itemIndex-1,0,item)
|
||||||
|
}else{
|
||||||
|
prizeList.value.splice(itemIndex,1)
|
||||||
|
prizeList.value.splice(itemIndex+1,0,item)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
onMounted(() => {
|
||||||
|
getImageDbStore()
|
||||||
|
})
|
||||||
|
watch(()=>prizeList,()=>{
|
||||||
|
console.log('prizeList',prizeList.value)
|
||||||
|
prizeConfig.setPrizeConfig(prizeList.value)
|
||||||
|
},{deep:true})
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
<h2>奖项配置</h2>
|
||||||
|
<ul>
|
||||||
|
<li v-for="item in prizeList" :key="item.id" class="flex gap-10">
|
||||||
|
<label class="w-full max-w-xs mb-10 form-control">
|
||||||
|
<!-- 向上向下 -->
|
||||||
|
<div class="flex flex-col items-center gap-2 pt-5">
|
||||||
|
<svg-icon class="hover:text-blue-400 cursor-pointer" :class="prizeList.indexOf(item)==0?'opacity-0 cursor-default':''" name="up" @click="sort(item,1)"></svg-icon>
|
||||||
|
<svg-icon class="hover:text-blue-400 cursor-pointer" name="down" @click="sort(item,0)" :class="prizeList.indexOf(item)==prizeList.length-1?'opacity-0 cursor-default':''"></svg-icon>
|
||||||
|
</div>
|
||||||
|
</label>
|
||||||
|
<label class="w-full max-w-xs mb-10 form-control">
|
||||||
|
<div class="label">
|
||||||
|
<span class="label-text">名称</span>
|
||||||
|
</div>
|
||||||
|
<input type="text" v-model="item.name" placeholder="名称" class="w-full input-sm max-w-xs input input-bordered" />
|
||||||
|
</label>
|
||||||
|
<label class="w-full max-w-xs mb-10 form-control">
|
||||||
|
<div class="label">
|
||||||
|
<span class="label-text">是否全员参加</span>
|
||||||
|
</div>
|
||||||
|
<input type="checkbox" :checked="item.isAll" @change="item.isAll =!item.isAll"
|
||||||
|
class="checkbox checkbox-secondary border-1 border-solid mt-2" />
|
||||||
|
</label>
|
||||||
|
<label class="w-full max-w-xs mb-10 form-control">
|
||||||
|
<div class="label">
|
||||||
|
<span class="label-text">获奖人数</span>
|
||||||
|
</div>
|
||||||
|
<input type="number" v-model="item.count" placeholder="获奖人数"
|
||||||
|
class="w-full max-w-xs input-sm input input-bordered" />
|
||||||
|
</label>
|
||||||
|
<label class="w-full max-w-xs mb-10 form-control">
|
||||||
|
<div class="label">
|
||||||
|
<span class="label-text">图片</span>
|
||||||
|
</div>
|
||||||
|
<select class="select select-warning w-full select-sm max-w-xs" v-model="item.picture">
|
||||||
|
<option disabled selected>选择一张图片</option>
|
||||||
|
<option v-for="picItem in imgList" :key="picItem.key">{{ picItem.key.split('+')[1] }}</option>
|
||||||
|
</select>
|
||||||
|
</label>
|
||||||
|
<label class="w-full max-w-xs mb-10 form-control">
|
||||||
|
<div class="label">
|
||||||
|
<span class="label-text">是否显示</span>
|
||||||
|
</div>
|
||||||
|
<input type="checkbox" :checked="item.isShow" @change="item.isShow =!item.isShow"
|
||||||
|
class="checkbox checkbox-secondary border-1 border-solid mt-2" />
|
||||||
|
</label>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
<button class="btn btn-info" @click="addPrize">添加</button>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<style lang='scss' scoped></style>
|
||||||
57
src/views/Config/index.vue
Normal file
57
src/views/Config/index.vue
Normal file
@@ -0,0 +1,57 @@
|
|||||||
|
<script setup lang="ts">
|
||||||
|
import { ref,onMounted } from 'vue';
|
||||||
|
import { useRouter } from 'vue-router';
|
||||||
|
import { configRoutes } from '../../router';
|
||||||
|
|
||||||
|
const router = useRouter();
|
||||||
|
const menuList = ref(configRoutes.children);
|
||||||
|
|
||||||
|
const cleanMenuList=(menu:any)=>{
|
||||||
|
const newList=menu;
|
||||||
|
for(let i=0;i<newList.length;i++){
|
||||||
|
if(newList[i].children){
|
||||||
|
cleanMenuList(newList[i].children);
|
||||||
|
}
|
||||||
|
if(!newList[i].meta){
|
||||||
|
newList.splice(i,1);
|
||||||
|
i--;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return newList;
|
||||||
|
}
|
||||||
|
menuList.value=cleanMenuList(menuList.value);
|
||||||
|
|
||||||
|
const skip=(path:string)=>{
|
||||||
|
router.push(path);
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<div class="flex">
|
||||||
|
<ul class="w-56 h-screen m-0 menu bg-base-200 pt-14 rounded-box">
|
||||||
|
<li v-for="item in menuList" :key="item.name">
|
||||||
|
<details open v-if="item.children">
|
||||||
|
<summary>{{ item.meta.title }}</summary>
|
||||||
|
<ul>
|
||||||
|
<li v-for="subItem in item.children" :key="subItem.name">
|
||||||
|
<details open v-if="subItem.children">
|
||||||
|
<summary>{{ subItem.meta.title }}</summary>
|
||||||
|
<ul>
|
||||||
|
<li v-for="subSubItem in subItem.children" :key="subSubItem.name">
|
||||||
|
<a @click="skip(subItem.path)">{{ subSubItem.meta!.title }}</a>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</details>
|
||||||
|
<a v-else @click="skip(subItem.path)">{{ subItem.meta!.title }}</a>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</details>
|
||||||
|
<a v-else @click="skip(item.path)">{{ item.meta!.title }}</a>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
<router-view></router-view>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<style scoped></style>
|
||||||
@@ -1,7 +0,0 @@
|
|||||||
<script setup lang="ts">
|
|
||||||
import { ref, reactive } from 'vue';
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<template>Doc</template>
|
|
||||||
|
|
||||||
<style scoped></style>
|
|
||||||
@@ -1,7 +0,0 @@
|
|||||||
<script setup lang="ts">
|
|
||||||
import { ref, reactive } from 'vue';
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<template>project</template>
|
|
||||||
|
|
||||||
<style scoped></style>
|
|
||||||
170
src/views/Home/data.ts
Normal file
170
src/views/Home/data.ts
Normal file
@@ -0,0 +1,170 @@
|
|||||||
|
export const tableData = [
|
||||||
|
'H', 'Hydrogen', '1.00794', 1, 1,
|
||||||
|
'He', 'Helium', '4.002602', 2, 1,
|
||||||
|
'Li', 'Lithium', '6.941', 3, 1,
|
||||||
|
'Be', 'Beryllium', '9.012182', 4, 1,
|
||||||
|
'B', 'Boron', '10.811', 13, 2,
|
||||||
|
'C', 'Carbon', '12.0107', 14, 2,
|
||||||
|
'N', 'Nitrogen', '14.0067', 15, 2,
|
||||||
|
'O', 'Oxygen', '15.9994', 16, 2,
|
||||||
|
'F', 'Fluorine', '18.9984032', 17, 2,
|
||||||
|
'Ne', 'Neon', '20.1797', 18, 2,
|
||||||
|
'Na', 'Sodium', '22.98976...', 1, 3,
|
||||||
|
'Mg', 'Magnesium', '24.305', 2, 3,
|
||||||
|
'Al', 'Aluminium', '26.9815386', 13, 3,
|
||||||
|
'Si', 'Silicon', '28.0855', 14, 3,
|
||||||
|
'P', 'Phosphorus', '30.973762', 15, 3,
|
||||||
|
'S', 'Sulfur', '32.065', 16, 3,
|
||||||
|
'Cl', 'Chlorine', '35.453', 17, 3,
|
||||||
|
'Ar', 'Argon', '39.948', 18, 3,
|
||||||
|
'K', 'Potassium', '39.948', 1, 4,
|
||||||
|
'Ca', 'Calcium', '40.078', 2, 4,
|
||||||
|
'Sc', 'Scandium', '44.955912', 3, 4,
|
||||||
|
'Ti', 'Titanium', '47.867', 4, 4,
|
||||||
|
'V', 'Vanadium', '50.9415', 5, 4,
|
||||||
|
'Cr', 'Chromium', '51.9961', 6, 4,
|
||||||
|
'Mn', 'Manganese', '54.938045', 7, 4,
|
||||||
|
'Fe', 'Iron', '55.845', 8, 4,
|
||||||
|
'Co', 'Cobalt', '58.933195', 9, 4,
|
||||||
|
'Ni', 'Nickel', '58.6934', 10, 4,
|
||||||
|
'Cu', 'Copper', '63.546', 11, 4,
|
||||||
|
'Zn', 'Zinc', '65.38', 12, 4,
|
||||||
|
'Ga', 'Gallium', '69.723', 13, 4,
|
||||||
|
'Ge', 'Germanium', '72.63', 14, 4,
|
||||||
|
'As', 'Arsenic', '74.9216', 15, 4,
|
||||||
|
'Se', 'Selenium', '78.96', 16, 4,
|
||||||
|
'Br', 'Bromine', '79.904', 17, 4,
|
||||||
|
'Kr', 'Krypton', '83.798', 18, 4,
|
||||||
|
'Rb', 'Rubidium', '85.4678', 1, 5,
|
||||||
|
'Sr', 'Strontium', '87.62', 2, 5,
|
||||||
|
'Y', 'Yttrium', '88.90585', 3, 5,
|
||||||
|
'Zr', 'Zirconium', '91.224', 4, 5,
|
||||||
|
'Nb', 'Niobium', '92.90628', 5, 5,
|
||||||
|
'Mo', 'Molybdenum', '95.96', 6, 5,
|
||||||
|
'Tc', 'Technetium', '(98)', 7, 5,
|
||||||
|
'Ru', 'Ruthenium', '101.07', 8, 5,
|
||||||
|
'Rh', 'Rhodium', '102.9055', 9, 5,
|
||||||
|
'Pd', 'Palladium', '106.42', 10, 5,
|
||||||
|
'Ag', 'Silver', '107.8682', 11, 5,
|
||||||
|
'Cd', 'Cadmium', '112.411', 12, 5,
|
||||||
|
'In', 'Indium', '114.818', 13, 5,
|
||||||
|
'Sn', 'Tin', '118.71', 14, 5,
|
||||||
|
'Sb', 'Antimony', '121.76', 15, 5,
|
||||||
|
'Te', 'Tellurium', '127.6', 16, 5,
|
||||||
|
'I', 'Iodine', '126.90447', 17, 5,
|
||||||
|
'Xe', 'Xenon', '131.293', 18, 5,
|
||||||
|
'Cs', 'Caesium', '132.9054', 1, 6,
|
||||||
|
'Ba', 'Barium', '132.9054', 2, 6,
|
||||||
|
'La', 'Lanthanum', '138.90547', 4, 9,
|
||||||
|
'Ce', 'Cerium', '140.116', 5, 9,
|
||||||
|
'Pr', 'Praseodymium', '140.90765', 6, 9,
|
||||||
|
'Nd', 'Neodymium', '144.242', 7, 9,
|
||||||
|
'Pm', 'Promethium', '(145)', 8, 9,
|
||||||
|
'Sm', 'Samarium', '150.36', 9, 9,
|
||||||
|
'Eu', 'Europium', '151.964', 10, 9,
|
||||||
|
'Gd', 'Gadolinium', '157.25', 11, 9,
|
||||||
|
'Tb', 'Terbium', '158.92535', 12, 9,
|
||||||
|
'Dy', 'Dysprosium', '162.5', 13, 9,
|
||||||
|
'Ho', 'Holmium', '164.93032', 14, 9,
|
||||||
|
'Er', 'Erbium', '167.259', 15, 9,
|
||||||
|
'Tm', 'Thulium', '168.93421', 16, 9,
|
||||||
|
'Yb', 'Ytterbium', '173.054', 17, 9,
|
||||||
|
'Lu', 'Lutetium', '174.9668', 18, 9,
|
||||||
|
'Hf', 'Hafnium', '178.49', 4, 6,
|
||||||
|
'Ta', 'Tantalum', '180.94788', 5, 6,
|
||||||
|
'W', 'Tungsten', '183.84', 6, 6,
|
||||||
|
'Re', 'Rhenium', '186.207', 7, 6,
|
||||||
|
'Os', 'Osmium', '190.23', 8, 6,
|
||||||
|
'Ir', 'Iridium', '192.217', 9, 6,
|
||||||
|
'Pt', 'Platinum', '195.084', 10, 6,
|
||||||
|
'Au', 'Gold', '196.966569', 11, 6,
|
||||||
|
'Hg', 'Mercury', '200.59', 12, 6,
|
||||||
|
'Tl', 'Thallium', '204.3833', 13, 6,
|
||||||
|
'Pb', 'Lead', '207.2', 14, 6,
|
||||||
|
'Bi', 'Bismuth', '208.9804', 15, 6,
|
||||||
|
'Po', 'Polonium', '(209)', 16, 6,
|
||||||
|
'At', 'Astatine', '(210)', 17, 6,
|
||||||
|
'Rn', 'Radon', '(222)', 18, 6,
|
||||||
|
'Fr', 'Francium', '(223)', 1, 7,
|
||||||
|
'Ra', 'Radium', '(226)', 2, 7,
|
||||||
|
'Ac', 'Actinium', '(227)', 4, 10,
|
||||||
|
'Th', 'Thorium', '232.03806', 5, 10,
|
||||||
|
'Pa', 'Protactinium', '231.0588', 6, 10,
|
||||||
|
'U', 'Uranium', '238.02891', 7, 10,
|
||||||
|
'Np', 'Neptunium', '(237)', 8, 10,
|
||||||
|
'Pu', 'Plutonium', '(244)', 9, 10,
|
||||||
|
'Am', 'Americium', '(243)', 10, 10,
|
||||||
|
'Cm', 'Curium', '(247)', 11, 10,
|
||||||
|
'Bk', 'Berkelium', '(247)', 12, 10,
|
||||||
|
'Cf', 'Californium', '(251)', 13, 10,
|
||||||
|
'Es', 'Einstenium', '(252)', 14, 10,
|
||||||
|
'Fm', 'Fermium', '(257)', 15, 10,
|
||||||
|
'Md', 'Mendelevium', '(258)', 16, 10,
|
||||||
|
'No', 'Nobelium', '(259)', 17, 10,
|
||||||
|
'Lr', 'Lawrencium', '(262)', 18, 10,
|
||||||
|
'Rf', 'Rutherfordium', '(267)', 4, 7,
|
||||||
|
'Db', 'Dubnium', '(268)', 5, 7,
|
||||||
|
'Sg', 'Seaborgium', '(271)', 6, 7,
|
||||||
|
'Bh', 'Bohrium', '(272)', 7, 7,
|
||||||
|
'Hs', 'Hassium', '(270)', 8, 7,
|
||||||
|
'Mt', 'Meitnerium', '(276)', 9, 7,
|
||||||
|
'Ds', 'Darmstadium', '(281)', 10, 7,
|
||||||
|
'Rg', 'Roentgenium', '(280)', 11, 7,
|
||||||
|
'Cn', 'Copernicium', '(285)', 12, 7,
|
||||||
|
'Uut', 'Unutrium', '(284)', 13, 7,
|
||||||
|
'Fl', 'Flerovium', '(289)', 14, 7,
|
||||||
|
'Uup', 'Ununpentium', '(288)', 15, 7,
|
||||||
|
'Lv', 'Livermorium', '(293)', 16, 7,
|
||||||
|
'Uus', 'Ununseptium', '(294)', 17, 7,
|
||||||
|
'Uuo', 'Ununoctium', '(294)', 18, 7
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
|
export const tableData2 = [
|
||||||
|
{
|
||||||
|
id:'1',
|
||||||
|
uid:'0002781821',
|
||||||
|
name:'黄飞虎',
|
||||||
|
department:'H',
|
||||||
|
other:'1.00794',
|
||||||
|
x:1,
|
||||||
|
y:1,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id:'2',
|
||||||
|
uid:'089281',
|
||||||
|
name:'欧阳飞剑',
|
||||||
|
department:'He',
|
||||||
|
other:'4.002602',
|
||||||
|
x:2,
|
||||||
|
y:1,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id:'3',
|
||||||
|
uid:'981721212',
|
||||||
|
name:'令狐冲',
|
||||||
|
department:'Li',
|
||||||
|
other:'6.941',
|
||||||
|
x:3,
|
||||||
|
y:1,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id:'4',
|
||||||
|
uid:'91888212',
|
||||||
|
name:'黄沾',
|
||||||
|
department:'Be',
|
||||||
|
other:9.012182,
|
||||||
|
x:4,
|
||||||
|
y:1,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id:'5',
|
||||||
|
uid:'918821212',
|
||||||
|
name:'林可致',
|
||||||
|
department:'B',
|
||||||
|
other:'10.811',
|
||||||
|
x:5,
|
||||||
|
y:1
|
||||||
|
}
|
||||||
|
|
||||||
|
]
|
||||||
@@ -1,70 +1,250 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { ref } from 'vue';
|
import { ref, onMounted } from 'vue'
|
||||||
import HelloWorld from '../../components/HelloWorld.vue';
|
// import { tableData2 as tableData } from './data'
|
||||||
import useStore from '@/store/index';
|
import * as THREE from 'three'
|
||||||
import { useRouter } from 'vue-router';
|
import {
|
||||||
import { IUser } from '@/types/user';
|
CSS3DRenderer, CSS3DObject
|
||||||
|
} from 'three/examples/jsm/renderers/CSS3DRenderer.js';
|
||||||
|
import { TrackballControls } from 'three/examples/jsm/controls/TrackballControls.js';
|
||||||
|
import TWEEN from 'three/examples/jsm/libs/tween.module.js';
|
||||||
|
import useStore from '@/store'
|
||||||
|
|
||||||
import { getData } from '@/api/main';
|
const personConfig=useStore().personConfig
|
||||||
const store = useStore();
|
const {getAlreadyPersonList:alreadyPersonList,getNotPersonList:notPersonList,getTableRowCount:rowCount}=personConfig
|
||||||
const router = useRouter();
|
const tableData=ref(
|
||||||
const data = ref<any>(null);
|
alreadyPersonList.concat(notPersonList)
|
||||||
const fetchData = async () => {
|
)
|
||||||
const res = await getData({});
|
|
||||||
data.value = res;
|
const containerRef = ref<HTMLElement>()
|
||||||
console.log('😊data.value:', data.value);
|
|
||||||
};
|
const scene = ref()
|
||||||
store.user.setUserList();
|
const camera = ref()
|
||||||
// eslint-disable-next-line no-undef
|
const renderer = ref()
|
||||||
let user = ref<IUser[]>([]);
|
const controls = ref()
|
||||||
const getUser = () => {
|
const objects = ref<any[]>([])
|
||||||
user.value = store.user.getUserList;
|
|
||||||
console.log('😊user.value:', user.value);
|
const targets = {
|
||||||
};
|
grid: <any[]>[],
|
||||||
const skip = (url: string) => {
|
helix: <any[]>[],
|
||||||
router.push({
|
table: <any[]>[],
|
||||||
path: url,
|
sphere: <any[]>[]
|
||||||
query: { id: 1 },
|
|
||||||
});
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const init = () => {
|
||||||
|
const felidView = 40;
|
||||||
|
const width = window.innerWidth;
|
||||||
|
const height = window.innerHeight;
|
||||||
|
const aspect = width / height;
|
||||||
|
const nearPlane = 1;
|
||||||
|
const farPlane = 10000;
|
||||||
|
const WebGLoutput = containerRef.value
|
||||||
|
|
||||||
|
scene.value = new THREE.Scene();
|
||||||
|
camera.value = new THREE.PerspectiveCamera(felidView, aspect, nearPlane, farPlane);
|
||||||
|
camera.value.position.z = 3000;
|
||||||
|
|
||||||
|
renderer.value = new CSS3DRenderer()
|
||||||
|
renderer.value.setSize(width, height)
|
||||||
|
renderer.value.domElement.style.position = 'absolute';
|
||||||
|
WebGLoutput!.appendChild(renderer.value.domElement);
|
||||||
|
|
||||||
|
controls.value = new TrackballControls(camera.value, renderer.value.domElement);
|
||||||
|
controls.value.rotateSpeed = 1;
|
||||||
|
controls.value.staticMoving = true;
|
||||||
|
controls.value.minDistance = 500;
|
||||||
|
controls.value.maxDistance = 6000;
|
||||||
|
controls.value.addEventListener('change', render);
|
||||||
|
|
||||||
|
const tableLen = tableData.value.length
|
||||||
|
for (let i = 0; i < tableLen; i++) {
|
||||||
|
const element = document.createElement('div');
|
||||||
|
element.className = 'element-card';
|
||||||
|
element.style.backgroundColor = `rgba( 0, 127, 127, ${Math.random() * 0.5 + 0.25} )`;
|
||||||
|
|
||||||
|
const number = document.createElement('div');
|
||||||
|
number.className = 'card-id';
|
||||||
|
// number.textContent = (i / 5 + 1).toString();
|
||||||
|
number.textContent = tableData.value[i].uid;
|
||||||
|
element.appendChild(number);
|
||||||
|
|
||||||
|
const symbol = document.createElement('div');
|
||||||
|
symbol.className = 'card-name';
|
||||||
|
symbol.textContent = tableData.value[i].name;
|
||||||
|
element.appendChild(symbol);
|
||||||
|
|
||||||
|
const detail = document.createElement('div');
|
||||||
|
detail.className = 'card-detail';
|
||||||
|
detail.innerHTML = `${tableData.value[i].department}<br/>${tableData.value[i].other}`;
|
||||||
|
element.appendChild(detail);
|
||||||
|
|
||||||
|
const object = new CSS3DObject(element);
|
||||||
|
object.position.x = Math.random() * 4000 - 2000;
|
||||||
|
object.position.y = Math.random() * 4000 - 2000;
|
||||||
|
object.position.z = Math.random() * 4000 - 2000;
|
||||||
|
scene.value.add(object);
|
||||||
|
|
||||||
|
objects.value.push(object);
|
||||||
|
}
|
||||||
|
|
||||||
|
createTableVertices();
|
||||||
|
createSphereVertices();
|
||||||
|
createHelixVertices();
|
||||||
|
|
||||||
|
function createTableVertices() {
|
||||||
|
const tableLen = tableData.value.length;
|
||||||
|
|
||||||
|
for (let i = 0; i < tableLen; i++) {
|
||||||
|
const object = new THREE.Object3D();
|
||||||
|
|
||||||
|
object.position.x = tableData.value[i].x * 180 - rowCount*90;
|
||||||
|
object.position.y = -tableData.value[i].y * 200 + 1000;
|
||||||
|
object.position.z = 0;
|
||||||
|
|
||||||
|
targets.table.push(object);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function createSphereVertices() {
|
||||||
|
let i = 0;
|
||||||
|
const objLength = objects.value.length;
|
||||||
|
const vector = new THREE.Vector3();
|
||||||
|
|
||||||
|
for (; i < objLength; ++i) {
|
||||||
|
let phi = Math.acos(-1 + (2 * i) / objLength);
|
||||||
|
let theta = Math.sqrt(objLength * Math.PI) * phi;
|
||||||
|
const object = new THREE.Object3D();
|
||||||
|
|
||||||
|
object.position.x = 800 * Math.cos(theta) * Math.sin(phi);
|
||||||
|
object.position.y = 800 * Math.sin(theta) * Math.sin(phi);
|
||||||
|
object.position.z = -800 * Math.cos(phi);
|
||||||
|
|
||||||
|
// rotation object
|
||||||
|
|
||||||
|
vector.copy(object.position).multiplyScalar(2);
|
||||||
|
object.lookAt(vector);
|
||||||
|
targets.sphere.push(object);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
function createHelixVertices() {
|
||||||
|
let i = 0;
|
||||||
|
const vector = new THREE.Vector3();
|
||||||
|
const objLength = objects.value.length;
|
||||||
|
for (; i < objLength; ++i) {
|
||||||
|
let phi = i * 0.213 + Math.PI;
|
||||||
|
|
||||||
|
const object = new THREE.Object3D();
|
||||||
|
|
||||||
|
object.position.x = 800 * Math.sin(phi);
|
||||||
|
object.position.y = -(i * 8) + 450;
|
||||||
|
object.position.z = 800 * Math.cos(phi + Math.PI);
|
||||||
|
|
||||||
|
object.scale.set(1.1, 1.1, 1.1);
|
||||||
|
|
||||||
|
vector.x = object.position.x * 2;
|
||||||
|
vector.y = object.position.y;
|
||||||
|
vector.z = object.position.z * 2;
|
||||||
|
|
||||||
|
object.lookAt(vector);
|
||||||
|
|
||||||
|
targets.helix.push(object);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
window.addEventListener('resize', onWindowResize, false);
|
||||||
|
transform(targets.table, 2000)
|
||||||
|
render();
|
||||||
|
}
|
||||||
|
|
||||||
|
const transform = (targets: any[], duration: number) => {
|
||||||
|
// TWEEN.removeAll();
|
||||||
|
const objLength = objects.value.length;
|
||||||
|
for (let i = 0; i < objLength; ++i) {
|
||||||
|
let object = objects.value[i];
|
||||||
|
let target = targets[i];
|
||||||
|
new TWEEN.Tween(object.position)
|
||||||
|
.to({ x: target.position.x, y: target.position.y, z: target.position.z },
|
||||||
|
Math.random() * duration + duration)
|
||||||
|
.easing(TWEEN.Easing.Exponential.InOut)
|
||||||
|
.start();
|
||||||
|
|
||||||
|
|
||||||
|
new TWEEN.Tween(object.rotation)
|
||||||
|
.to({ x: target.rotation.x, y: target.rotation.y, z: target.rotation.z }, Math.random() * duration + duration)
|
||||||
|
.easing(TWEEN.Easing.Exponential.InOut)
|
||||||
|
.start();
|
||||||
|
}
|
||||||
|
|
||||||
|
// 这个补间用来在位置与旋转补间同步执行,通过onUpdate在每次更新数据后渲染scene和camera
|
||||||
|
new TWEEN.Tween({})
|
||||||
|
.to({}, duration * 2)
|
||||||
|
.onUpdate(render)
|
||||||
|
.start();
|
||||||
|
}
|
||||||
|
function onWindowResize() {
|
||||||
|
camera.value.aspect = window.innerWidth / window.innerHeight
|
||||||
|
camera.value.updateProjectionMatrix();
|
||||||
|
|
||||||
|
renderer.value.setSize(window.innerWidth, window.innerHeight);
|
||||||
|
render();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* [animation update all tween && controls]
|
||||||
|
*/
|
||||||
|
function animation() {
|
||||||
|
TWEEN.update();
|
||||||
|
controls.value.update();
|
||||||
|
requestAnimationFrame(animation);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function render() {
|
||||||
|
renderer.value.render(scene.value, camera.value);
|
||||||
|
}
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
init();
|
||||||
|
animation();
|
||||||
|
});
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<div class="flex justify-center">
|
<div id="container" ref="containerRef">
|
||||||
<!-- <svg-icon :name="'menu'" class="cursor-pointer svgMenu"></svg-icon> -->
|
<!-- 选中菜单结构 start-->
|
||||||
<a href="https://vitejs.dev" target="_blank">
|
<div id="menu">
|
||||||
<img src="/vite.svg" class="logo" alt="Vite logo" />
|
<button id="table" @click="transform(targets.table, 2000)">TABLE</button>
|
||||||
</a>
|
<button id="sphere" @click="transform(targets.sphere, 2000)">SPHERE</button>
|
||||||
<a href="https://vuejs.org/" target="_blank">
|
<button id="helix" @click="transform(targets.helix, 2000)">HELIX</button>
|
||||||
<img src="../../assets/vue.svg" class="logo vue" alt="Vue logo" />
|
|
||||||
</a>
|
|
||||||
</div>
|
</div>
|
||||||
<div class="flex justify-center gap-6">
|
<!-- end -->
|
||||||
<button class="btn btn-primary" @click="getUser">pinia test</button>
|
|
||||||
<button class="btn btn-outline btn-secondary" @click="skip('about')"> router test</button>
|
|
||||||
<button class="btn glass" @click="fetchData">fetch</button>
|
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
<HelloWorld
|
|
||||||
class="flex flex-col items-center mx-auto text-center flex-column"
|
|
||||||
msg="Vite + Vue"
|
|
||||||
/>
|
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<style scoped lang="scss">
|
<style scoped lang="scss">
|
||||||
|
#menu {
|
||||||
|
position: absolute;
|
||||||
.logo {
|
z-index: 100;
|
||||||
height: 10em;
|
width: 100%;
|
||||||
padding: 1.5em;
|
bottom: 50px;
|
||||||
will-change: filter;
|
text-align: center;
|
||||||
z-index: 0;
|
font-size: 32px;
|
||||||
}
|
}
|
||||||
.logo:hover {
|
|
||||||
filter: drop-shadow(0 0 2em #646cffaa);
|
button {
|
||||||
|
border: none;
|
||||||
|
background-color: transparent;
|
||||||
|
color: rgba(127, 255, 255, 0.75);
|
||||||
|
padding: 12px 24px;
|
||||||
|
cursor: pointer;
|
||||||
|
outline: 1px solid rgba(127, 255, 255, 0.75);
|
||||||
}
|
}
|
||||||
.logo.vue:hover {
|
|
||||||
filter: drop-shadow(0 0 2em #42b883aa);
|
button:hover {
|
||||||
|
background-color: rgba(127, 255, 255, 0.5);
|
||||||
|
}
|
||||||
|
|
||||||
|
button:active {
|
||||||
|
background-color: rgba(127, 255, 255, 0.75);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -91,7 +91,6 @@ export default defineConfig(({ mode }) => {
|
|||||||
resolve: {
|
resolve: {
|
||||||
alias: {
|
alias: {
|
||||||
'@': path.resolve(__dirname, './src'),
|
'@': path.resolve(__dirname, './src'),
|
||||||
'~bootstrap': path.resolve(__dirname, 'node_modules/bootstrap'),
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
build: {
|
build: {
|
||||||
|
|||||||
Reference in New Issue
Block a user