feat: new

This commit is contained in:
ex_zhangwenlei@exiot.cmcc
2024-01-06 00:53:50 +08:00
parent f66a1d2ae9
commit 4076bbe72e
27 changed files with 1094 additions and 158 deletions

View File

@@ -5,7 +5,7 @@
<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 + Vue + TS</title>
<title>Log-Lottery</title>
</head>
<body>

View File

@@ -15,16 +15,21 @@
"dependencies": {
"@element-plus/icons-vue": "^2.1.0",
"@popperjs/core": "^2.11.8",
"@radial-color-picker/vue-color-picker": "^5.0.1",
"@vueuse/core": "^10.6.1",
"axios": "^1.6.1",
"localforage": "^1.10.0",
"pinia": "^2.1.7",
"pinia-plugin-persist": "^1.0.0",
"svg-sprite-loader": "^6.0.11",
"theme-change": "^2.5.0",
"three": "^0.160.0",
"three-css2drender": "^1.0.0",
"vcolorpicker": "^2.0.12",
"vue": "^3.3.8",
"vue-accessible-color-picker": "^5.0.1",
"vue-router": "^4.2.5",
"vue3-colorpicker": "^2.2.3",
"xlsx": "^0.18.5",
"zod": "^3.22.4"
},

342
pnpm-lock.yaml generated
View File

@@ -11,6 +11,9 @@ dependencies:
'@popperjs/core':
specifier: ^2.11.8
version: 2.11.8
'@radial-color-picker/vue-color-picker':
specifier: ^5.0.1
version: 5.0.1(vue@3.3.8)
'@vueuse/core':
specifier: ^10.6.1
version: 10.6.1(vue@3.3.8)
@@ -29,18 +32,30 @@ dependencies:
svg-sprite-loader:
specifier: ^6.0.11
version: 6.0.11
theme-change:
specifier: ^2.5.0
version: 2.5.0
three:
specifier: ^0.160.0
version: 0.160.0
three-css2drender:
specifier: ^1.0.0
version: 1.0.0(three@0.160.0)
vcolorpicker:
specifier: ^2.0.12
version: 2.0.12(typescript@5.2.2)
vue:
specifier: ^3.3.8
version: 3.3.8(typescript@5.2.2)
vue-accessible-color-picker:
specifier: ^5.0.1
version: 5.0.1(vue@3.3.8)
vue-router:
specifier: ^4.2.5
version: 4.2.5(vue@3.3.8)
vue3-colorpicker:
specifier: ^2.2.3
version: 2.2.3(@aesoper/normal-utils@0.1.5)(@popperjs/core@2.11.8)(@vueuse/core@10.6.1)(gradient-parser@1.0.2)(lodash-es@4.17.21)(tinycolor2@1.6.0)(vue-types@4.2.1)(vue@3.3.8)
xlsx:
specifier: ^0.18.5
version: 0.18.5
@@ -162,11 +177,35 @@ packages:
engines: {node: '>=0.10.0'}
dev: true
/@aesoper/normal-utils@0.1.5:
resolution: {integrity: sha512-LFF/6y6h5mfwhnJaWqqxuC8zzDaHCG62kMRkd8xhDtq62TQj9dM17A9DhE87W7DhiARJsHLgcina/9P4eNCN1w==}
dev: false
/@alloc/quick-lru@5.2.0:
resolution: {integrity: sha512-UrcABB+4bUrFABwbluTIBErXwvbsU/V7TZWfmbgJfbkwiBuziS9gxdODUyuiecfdGQ85jglMW6juS3+z5TsKLw==}
engines: {node: '>=10'}
dev: true
/@ant-design/colors@6.0.0:
resolution: {integrity: sha512-qAZRvPzfdWHtfameEGP2Qvuf838NhergR35o+EuVyB5XvSA98xod5r4utvi4TJ3ywmevm290g9nsCG5MryrdWQ==}
dependencies:
'@ctrl/tinycolor': 3.6.1
dev: false
/@ant-design/icons-svg@4.3.1:
resolution: {integrity: sha512-4QBZg8ccyC6LPIRii7A0bZUk3+lEDCLnhB+FVsflGdcWPPmV+j3fire4AwwoqHV/BibgvBmR9ZIo4s867smv+g==}
dev: false
/@ant-design/icons-vue@6.1.0(vue@3.3.8):
resolution: {integrity: sha512-EX6bYm56V+ZrKN7+3MT/ubDkvJ5rK/O2t380WFRflDcVFgsvl3NLH7Wxeau6R8DbrO5jWR6DSTC3B6gYFp77AA==}
peerDependencies:
vue: '>=3.0.3'
dependencies:
'@ant-design/colors': 6.0.0
'@ant-design/icons-svg': 4.3.1
vue: 3.3.8(typescript@5.2.2)
dev: false
/@antfu/install-pkg@0.1.1:
resolution: {integrity: sha512-LyB/8+bSfa0DFGC06zpCEfs89/XoWZwws5ygEa5D+Xsm3OfI+aXQ86VgVG7Acyef+rSZ5HE7J8rrxzrQeM3PjQ==}
dependencies:
@@ -215,7 +254,6 @@ packages:
engines: {node: '>=6.9.0'}
dependencies:
regenerator-runtime: 0.14.0
dev: true
/@babel/types@7.23.3:
resolution: {integrity: sha512-OZnvoH2l8PK5eUvEcUyCt/sXgr/h+UWpVuBbOljwcrAgUl6lpchoQ++PHGyQy1AtYnVA6CEq3y5xeEI10brpXw==}
@@ -225,6 +263,11 @@ packages:
'@babel/helper-validator-identifier': 7.22.20
to-fast-properties: 2.0.0
/@ctrl/tinycolor@3.6.1:
resolution: {integrity: sha512-SITSV6aIXsuVNV3f3O0f2n/cgyEDWoSqtZMYiAmcsYHydcKrOz3gUxB/iXd/Qf08+IZX4KpgNbvUdMBmWz+kcA==}
engines: {node: '>=10'}
dev: false
/@element-plus/icons-vue@2.1.0(vue@3.3.8):
resolution: {integrity: sha512-PSBn3elNoanENc1vnCfh+3WA9fimRC7n+fWkf3rE5jvv+aBohNHABC/KAR5KWPecxWxDTVT1ERpRbOMRcOV/vA==}
peerDependencies:
@@ -612,6 +655,19 @@ packages:
resolution: {integrity: sha512-P1st0aksCrn9sGZhp8GMYwBnQsbvAWsZAX44oXNNvLHGqAOcoVxmjZiohstwQ7SqKnbR47akdNi+uleWD8+g6A==}
dev: false
/@radial-color-picker/rotator@3.0.2:
resolution: {integrity: sha512-JiSVkN/hSMKqIcQz8KaeLvbzA0UrZkKQL2Q8s4MUxehjLcciTSctG75V8trHk0tPkTfglZjLlmg+S5+xO3GBLQ==}
dev: false
/@radial-color-picker/vue-color-picker@5.0.1(vue@3.3.8):
resolution: {integrity: sha512-ExTbaDdac00RqxCPcfWKj2UrtBbzwph0HRVQKKgj94aCkWz8vedme+65v97cZUCdxOvxh0BANGgi6RD6H966Zw==}
peerDependencies:
vue: ^3.0.0
dependencies:
'@radial-color-picker/rotator': 3.0.2
vue: 3.3.8(typescript@5.2.2)
dev: false
/@rollup/pluginutils@5.0.5:
resolution: {integrity: sha512-6aEYR910NyP73oHiJglti74iRyOwgFU4x3meH/H8OJx6Ry0j6cOVZ5X/wTvub7G7Ao6qaHBEaNsV3GLJkSsF+Q==}
engines: {node: '>=14.0.0'}
@@ -626,6 +682,13 @@ packages:
picomatch: 2.3.1
dev: true
/@simonwep/pickr@1.8.2:
resolution: {integrity: sha512-/l5w8BIkrpP6n1xsetx9MWPWlU6OblN5YgZZphxan0Tq4BByTCETL6lyIeY8lagalS2Nbt4F2W034KHLIiunKA==}
dependencies:
core-js: 3.35.0
nanopop: 2.3.0
dev: false
/@sinclair/typebox@0.27.8:
resolution: {integrity: sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA==}
dev: true
@@ -747,6 +810,10 @@ packages:
meshoptimizer: 0.18.1
dev: true
/@types/web-bluetooth@0.0.16:
resolution: {integrity: sha512-oh8q2Zc32S6gd/j50GowEjKLoOVOwHP/bWVjKJInBwQqdOYMdPrf1oVlelTlyfFK3CKxL1uahMDAr+vy8T7yMQ==}
dev: false
/@types/web-bluetooth@0.0.20:
resolution: {integrity: sha512-g9gZnnXVq7gM7v3tJCWV/qw7w+KeOlSHAhgF9RytFyifW6AF61hdT2ucrYhPq9hLs5JIryeupHV3qGk95dH9ow==}
@@ -1093,9 +1160,25 @@ packages:
- '@vue/composition-api'
- vue
/@vueuse/core@9.13.0(vue@3.3.8):
resolution: {integrity: sha512-pujnclbeHWxxPRqXWmdkKV5OX4Wk4YeK7wusHqRwU0Q7EFusHoqNA/aPhB6KCh9hEqJkLAJo7bb0Lh9b+OIVzw==}
dependencies:
'@types/web-bluetooth': 0.0.16
'@vueuse/metadata': 9.13.0
'@vueuse/shared': 9.13.0(vue@3.3.8)
vue-demi: 0.14.6(vue@3.3.8)
transitivePeerDependencies:
- '@vue/composition-api'
- vue
dev: false
/@vueuse/metadata@10.6.1:
resolution: {integrity: sha512-qhdwPI65Bgcj23e5lpGfQsxcy0bMjCAsUGoXkJ7DsoeDUdasbZ2DBa4dinFCOER3lF4gwUv+UD2AlA11zdzMFw==}
/@vueuse/metadata@9.13.0:
resolution: {integrity: sha512-gdU7TKNAUVlXXLbaF+ZCfte8BjRJQWPCa2J55+7/h+yDtzw3vOoGQDRXzI6pyKyo6bXFT5/QoPE4hAknExjRLQ==}
dev: false
/@vueuse/shared@10.6.1(vue@3.3.8):
resolution: {integrity: sha512-TECVDTIedFlL0NUfHWncf3zF9Gc4VfdxfQc8JFwoVZQmxpONhLxFrlm0eHQeidHj4rdTPL3KXJa0TZCk1wnc5Q==}
dependencies:
@@ -1104,6 +1187,15 @@ packages:
- '@vue/composition-api'
- vue
/@vueuse/shared@9.13.0(vue@3.3.8):
resolution: {integrity: sha512-UrnhU+Cnufu4S6JLCPZnkWh0WwZGUp72ktOF2DFptMlOs3TOdVv8xJN53zhHGARmVOsz5KqOls09+J1NR6sBKw==}
dependencies:
vue-demi: 0.14.6(vue@3.3.8)
transitivePeerDependencies:
- '@vue/composition-api'
- vue
dev: false
/@webassemblyjs/ast@1.11.6:
resolution: {integrity: sha512-IN1xI7PwOvLPgjcf180gC1bqn3q/QaOCwYUahIOhbYUu8KA/3tw2RT/T0Gidi1l7Hhj5D/INhJxiICObqpMu4Q==}
dependencies:
@@ -1327,6 +1419,32 @@ packages:
engines: {node: '>=12'}
dev: true
/ant-design-vue@3.2.20(vue@3.3.8):
resolution: {integrity: sha512-YWpMfGaGoRastIXEYfCoJiaRiDHk4chqtYhlKQM5GqPt6NfvrM1Vg2e60yHtjxlZjed91wCMm0rAmyUr7Hwzdg==}
engines: {node: '>=12.22.0'}
peerDependencies:
vue: '>=3.2.0'
dependencies:
'@ant-design/colors': 6.0.0
'@ant-design/icons-vue': 6.1.0(vue@3.3.8)
'@babel/runtime': 7.23.2
'@ctrl/tinycolor': 3.6.1
'@simonwep/pickr': 1.8.2
array-tree-filter: 2.1.0
async-validator: 4.2.5
dayjs: 1.11.10
dom-align: 1.12.4
dom-scroll-into-view: 2.0.1
lodash: 4.17.21
lodash-es: 4.17.21
resize-observer-polyfill: 1.5.1
scroll-into-view-if-needed: 2.2.31
shallow-equal: 1.2.1
vue: 3.3.8(typescript@5.2.2)
vue-types: 3.0.2(vue@3.3.8)
warning: 4.0.3
dev: false
/any-promise@1.3.0:
resolution: {integrity: sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A==}
dev: true
@@ -1372,6 +1490,10 @@ packages:
is-array-buffer: 3.0.2
dev: true
/array-tree-filter@2.1.0:
resolution: {integrity: sha512-4ROwICNlNw/Hqa9v+rk5h22KjmzB1JGTMVKP2AKJBOCgb0yL0ASf0+YvCcLNNwquOHNX48jkeZIJ3a+oOQqKcw==}
dev: false
/array-union@2.1.0:
resolution: {integrity: sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==}
engines: {node: '>=8'}
@@ -1389,6 +1511,10 @@ packages:
resolution: {integrity: sha512-Q+JC7Whu8HhmTdBph/Tq59IoRtoy6KAm5zzPv00WdujX82lbAL8K7WVjne7vdCsAmbF4AYaDOPyO3k0kl8qIrw==}
engines: {node: '>=0.10.0'}
/async-validator@4.2.5:
resolution: {integrity: sha512-7HhHjtERjqlNbZtqNqy2rckN/SpOOlmDliet+lP7k+eKZEjPk3DgyeU9lIXLdeLz0uBbbVp+9Qdow9wJWgwwfg==}
dev: false
/asynckit@0.4.0:
resolution: {integrity: sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==}
@@ -1728,6 +1854,10 @@ packages:
/component-emitter@1.3.0:
resolution: {integrity: sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg==}
/compute-scroll-into-view@1.0.20:
resolution: {integrity: sha512-UCB0ioiyj8CRjtrvaceBLqqhZCVP+1B8+NWQhmdsm0VXOJtobBCf1dBQmebCCo34qZmUwZfIH2MZLqNHazrfjg==}
dev: false
/computeds@0.0.1:
resolution: {integrity: sha512-7CEBgcMjVmitjYo5q8JTJVra6X5mQ20uTThdK+0kR7UEaDrAWEQcRiBtWJzga4eRpP6afNwwLsX2SET2JhVB1Q==}
dev: true
@@ -1747,6 +1877,11 @@ packages:
resolution: {integrity: sha512-XgZ0pFcakEUlbwQEVNg3+QAis1FyTL3Qel9FYy8pSkQqoG3PNoT0bOCQtOXcOkur21r2Eq2kI+IE+gsmAEVlYw==}
engines: {node: '>=0.10.0'}
/core-js@3.35.0:
resolution: {integrity: sha512-ntakECeqg81KqMueeGJ79Q5ZgQNR+6eaE8sxGCx62zMbAIj65q+uYvatToew3m6eAGdU4gNZwpZ34NMe4GYswg==}
requiresBuild: true
dev: false
/cors@2.8.5:
resolution: {integrity: sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==}
engines: {node: '>= 0.10'}
@@ -1853,6 +1988,10 @@ packages:
whatwg-url: 12.0.1
dev: true
/dayjs@1.11.10:
resolution: {integrity: sha512-vjAczensTgRcqDERK0SR2XMwsF/tSvnvlv6VcF2GIhg6Sx4yOIt/irsr1RDJsKiIyBzJDpCoXiWWq28MqH2cnQ==}
dev: false
/de-indent@1.0.2:
resolution: {integrity: sha512-e/1zu3xH5MQryN2zdVaF0OrdNLUbvWxzMbi+iNA6Bky7l1RoP8a2fIbRocyHclXt/arDrrR6lL3TqFD9pMQTsg==}
dev: true
@@ -2027,6 +2166,14 @@ packages:
resolution: {integrity: sha512-X7BJ2yElsnOJ30pZF4uIIDfBEVgF4XEBxL9Bxhy6dnrm5hkzqmsWHGTiHqRiITNhMyFLyAiWndIJP7Z1NTteDg==}
dev: true
/dom-align@1.12.4:
resolution: {integrity: sha512-R8LUSEay/68zE5c8/3BDxiTEvgb4xZTF0RKmAHfiEVN3klfIpXfi2/QCoiWPccVQ0J/ZGdz9OjzL4uJEP/MRAw==}
dev: false
/dom-scroll-into-view@2.0.1:
resolution: {integrity: sha512-bvVTQe1lfaUr1oFzZX80ce9KLDlZ3iU+XGNE/bz9HnGdklTieqsbmsLHe+rT2XWqopvL0PckkYqN7ksmm5pe3w==}
dev: false
/dom-serializer@0.2.2:
resolution: {integrity: sha512-2/xPb3ORsQ42nHYiSunXkDjPLBaEj/xTwUO4B7XCZQTRk7EBtTOPaygh10YAAh2OI1Qrp6NWfpAhzswj0ydt9g==}
dependencies:
@@ -2695,6 +2842,11 @@ packages:
resolution: {integrity: sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==}
dev: true
/gradient-parser@1.0.2:
resolution: {integrity: sha512-gR6nY33xC9yJoH4wGLQtZQMXDi6RI3H37ERu7kQCVUzlXjNedpZM7xcA489Opwbq0BSGohtWGsWsntupmxelMg==}
engines: {node: '>=0.10.0'}
dev: false
/graphemer@1.4.0:
resolution: {integrity: sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==}
dev: true
@@ -2794,6 +2946,11 @@ packages:
resolution: {integrity: sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==}
hasBin: true
/highlight.js@11.9.0:
resolution: {integrity: sha512-fJ7cW7fQGCYAkgv4CPfwFHrfd/cLS4Hau96JuJ+ZTOWhjnhoeN1ub1tFmALm/+lW5z4WCAuAV9bm05AP0mS6Gw==}
engines: {node: '>=12.0.0'}
dev: false
/html-encoding-sniffer@3.0.0:
resolution: {integrity: sha512-oWv4T4yJ52iKrufjnyZPkrN0CH3QnrUqdB6In1g5Fe1mia8GmF36gnfNySxoZtxD5+NmYw1EElVXiBk93UeskA==}
engines: {node: '>=12'}
@@ -3081,6 +3238,16 @@ packages:
dependencies:
isobject: 3.0.1
/is-plain-object@3.0.1:
resolution: {integrity: sha512-Xnpx182SBMrr/aBik8y+GuR4U1L9FqMSojwDQwPMmxyC6bvEqly9UBCxhauBF5vNh2gwWJNX6oDV7O+OM4z34g==}
engines: {node: '>=0.10.0'}
dev: false
/is-plain-object@5.0.0:
resolution: {integrity: sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q==}
engines: {node: '>=0.10.0'}
dev: false
/is-potential-custom-element-name@1.0.1:
resolution: {integrity: sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ==}
dev: true
@@ -3216,7 +3383,6 @@ packages:
/js-tokens@4.0.0:
resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==}
dev: true
/js-yaml@4.1.0:
resolution: {integrity: sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==}
@@ -3389,6 +3555,10 @@ packages:
p-locate: 5.0.0
dev: true
/lodash-es@4.17.21:
resolution: {integrity: sha512-mKnC+QJ9pWVzv+C4/U3rRsHapFfHvQFoFB92e52xeyGMcX6/OlIl78je1u8vePzYZSkkogMPJ2yjxxsb89cxyw==}
dev: false
/lodash.castarray@4.4.0:
resolution: {integrity: sha512-aVx8ztPv7/2ULbArGJ2Y42bG1mEQ5mGjpdvrbJcJFU3TbYybe+QlLS4pst9zV52ymy2in1KpFPiZnAOATxD4+Q==}
dev: true
@@ -3403,7 +3573,13 @@ packages:
/lodash@4.17.21:
resolution: {integrity: sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==}
dev: true
/loose-envify@1.4.0:
resolution: {integrity: sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==}
hasBin: true
dependencies:
js-tokens: 4.0.0
dev: false
/loupe@2.3.7:
resolution: {integrity: sha512-zSMINGVYkdpYSOBmLi0D1Uo7JU9nVdQKrHxC8eYlV+9YKK9WePqAlL7lSlorG/U2Fw1w0hTBmaa/jrQ3UbPHtA==}
@@ -3612,6 +3788,10 @@ packages:
transitivePeerDependencies:
- supports-color
/nanopop@2.3.0:
resolution: {integrity: sha512-fzN+T2K7/Ah25XU02MJkPZ5q4Tj5FpjmIYq4rvoHX4yb16HzFdCO6JxFFn5Y/oBhQ8no8fUZavnyIv9/+xkBBw==}
dev: false
/natural-compare@1.4.0:
resolution: {integrity: sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==}
dev: true
@@ -4154,7 +4334,6 @@ packages:
/regenerator-runtime@0.14.0:
resolution: {integrity: sha512-srw17NI0TUWHuGa5CFGGmhfNIeja30WMBfbslPNhf6JrqQlLN5gcrvig1oqPxiVaXb0oW0XRKtH6Nngs5lKCIA==}
dev: true
/regex-not@1.0.2:
resolution: {integrity: sha512-J6SDjUgDxQj5NusnOtdFxDwN/+HWykR8GELwctJ7mdqhcyy1xEc4SRFHUXvxTp661YaVKAjfRLZ9cCqS6tn32A==}
@@ -4189,6 +4368,10 @@ packages:
resolution: {integrity: sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==}
dev: true
/resize-observer-polyfill@1.5.1:
resolution: {integrity: sha512-LwZrotdHOo12nQuZlHEmtuXdqGoOD0OhaxopaNFxWzInpEgaLWoVuAMbTzixuosCx2nEG58ngzW3vxdWoxIgdg==}
dev: false
/resolve-from@4.0.0:
resolution: {integrity: sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==}
engines: {node: '>=4'}
@@ -4326,6 +4509,12 @@ packages:
ajv-keywords: 3.5.2(ajv@6.12.6)
dev: true
/scroll-into-view-if-needed@2.2.31:
resolution: {integrity: sha512-dGCXy99wZQivjmjIqihaBQNjryrz5rueJY7eHfTdyWEiR4ttYpsajb14rn9s5d4DY4EcY6+4+U/maARBXJedkA==}
dependencies:
compute-scroll-into-view: 1.0.20
dev: false
/scule@1.0.0:
resolution: {integrity: sha512-4AsO/FrViE/iDNEPaAQlb77tf0csuq27EsVpy6ett584EcRTp6pTDLoGWVxCD77y5iU5FauOvhsI4o1APwPoSQ==}
dev: true
@@ -4372,6 +4561,10 @@ packages:
is-plain-object: 2.0.4
split-string: 3.1.0
/shallow-equal@1.2.1:
resolution: {integrity: sha512-S4vJDjHHMBaiZuT9NPb616CSmLf618jawtv3sufLl6ivK8WocjAo58cXwbRV1cgqxH0Qbv+iUt6m05eqEa2IRA==}
dev: false
/shebang-command@2.0.0:
resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==}
engines: {node: '>=8'}
@@ -4783,6 +4976,10 @@ packages:
resolution: {integrity: sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==}
dev: true
/theme-change@2.5.0:
resolution: {integrity: sha512-B/UdsgdHAGhSKHTAQnxg/etN0RaMDpehuJmZIjLMDVJ6DGIliRHGD6pODi1CXLQAN9GV0GSyB3G6yCuK05PkPQ==}
dev: false
/thenify-all@1.6.0:
resolution: {integrity: sha512-RNxQH/qI8/t3thXJDwcstUO4zeqo64+Uy/+sNVRBx4Xn2OX+OZ9oP+iJnNFqplFra2ZUVeKCSa2oVWi3T4uVmA==}
engines: {node: '>=0.8'}
@@ -4812,6 +5009,10 @@ packages:
resolution: {integrity: sha512-65NKvSuAVDP/n4CqH+a9w2kTlLReS9vhsAP06MWx+/89nMinJyB2icyl58RIcqCmIggpojIGeuJGhjU1aGMBSg==}
dev: true
/tinycolor2@1.6.0:
resolution: {integrity: sha512-XPaBkWQJdsf3pLKJV9p4qN/S+fm2Oj8AIPo1BTUhg5oxkvm9+SVEGFdhyOz7tTdUTfvxMiAs4sp6/eZO2Ew+pw==}
dev: false
/tinypool@0.7.0:
resolution: {integrity: sha512-zSYNUlYSMhJ6Zdou4cJwo/p7w5nmAH17GRfU/ui3ctvjXFErXXkruT4MWW6poDeXgCaIBlGLrfU6TbTXxyGMww==}
engines: {node: '>=14.0.0'}
@@ -5129,6 +5330,83 @@ packages:
engines: {node: '>= 0.8'}
dev: true
/vcolorpicker@2.0.10(typescript@5.2.2):
resolution: {integrity: sha512-5MwXNF9CoPs0d3ZhcFbvjrGFTApUQQXdZXEScLKjDg3CFs/YRLCVoSgS0d0WJVJr323rB15bxdpI5ydlUzcl7g==}
dependencies:
'@vueuse/core': 9.13.0(vue@3.3.8)
ant-design-vue: 3.2.20(vue@3.3.8)
highlight.js: 11.9.0
vcolorpicker: 2.0.9(typescript@5.2.2)
vue: 3.3.8(typescript@5.2.2)
transitivePeerDependencies:
- '@vue/composition-api'
- typescript
dev: false
/vcolorpicker@2.0.11(typescript@5.2.2):
resolution: {integrity: sha512-S1yqvUxvow7fcdtNGPJlBQMXVZt3dp9o4xpPhycwg+yciKNIcUu9nyO+wXDe/htpObpob4g2Djd84i6JWSmrWA==}
dependencies:
'@vueuse/core': 9.13.0(vue@3.3.8)
ant-design-vue: 3.2.20(vue@3.3.8)
highlight.js: 11.9.0
vcolorpicker: 2.0.10(typescript@5.2.2)
vue: 3.3.8(typescript@5.2.2)
transitivePeerDependencies:
- '@vue/composition-api'
- typescript
dev: false
/vcolorpicker@2.0.12(typescript@5.2.2):
resolution: {integrity: sha512-a1GG/qUGfIGcnRcompFJJ4zhCiUCnRga/viE5vC7YDEr6yx9gbSo4sAZlG8OmxDx/BZxkTyFHaZ7TOCxTW1a+g==}
dependencies:
'@vueuse/core': 9.13.0(vue@3.3.8)
highlight.js: 11.9.0
vcolorpicker: 2.0.11(typescript@5.2.2)
vue: 3.3.8(typescript@5.2.2)
transitivePeerDependencies:
- '@vue/composition-api'
- typescript
dev: false
/vcolorpicker@2.0.5(typescript@5.2.2):
resolution: {integrity: sha512-WLxch6FZTCrSia43TJgG2vspaB8NZRw2mVPSsK31kZWgx6xYUyTjqDZp/zFxhuDcThOqTSoFG0EBxfZy5wn9lQ==}
dependencies:
'@vueuse/core': 9.13.0(vue@3.3.8)
ant-design-vue: 3.2.20(vue@3.3.8)
highlight.js: 11.9.0
vcolorpicker: 2.0.12(typescript@5.2.2)
vue: 3.3.8(typescript@5.2.2)
transitivePeerDependencies:
- '@vue/composition-api'
- typescript
dev: false
/vcolorpicker@2.0.8(typescript@5.2.2):
resolution: {integrity: sha512-8Jv6cQfzcGP0cWCV81Kq52qp7xrX5bVjzEozYH5TorEeqWB71Ptj/6+CcOCU45NYgF6jOfGAsGZxjPwkboHDMw==}
dependencies:
'@vueuse/core': 9.13.0(vue@3.3.8)
ant-design-vue: 3.2.20(vue@3.3.8)
highlight.js: 11.9.0
vcolorpicker: 2.0.5(typescript@5.2.2)
vue: 3.3.8(typescript@5.2.2)
transitivePeerDependencies:
- '@vue/composition-api'
- typescript
dev: false
/vcolorpicker@2.0.9(typescript@5.2.2):
resolution: {integrity: sha512-vTMr2/kpumhWan4seGugXfh4R55s266asALfF5wM4EZfNVAgXy23+wgyiVVzXQe7Rk3F4wNtVP/sKrLEIPJTIw==}
dependencies:
'@vueuse/core': 9.13.0(vue@3.3.8)
ant-design-vue: 3.2.20(vue@3.3.8)
highlight.js: 11.9.0
vcolorpicker: 2.0.8(typescript@5.2.2)
vue: 3.3.8(typescript@5.2.2)
transitivePeerDependencies:
- '@vue/composition-api'
- typescript
dev: false
/vite-node@0.34.6(@types/node@20.9.0)(sass@1.69.5):
resolution: {integrity: sha512-nlBMJ9x6n7/Amaz6F3zJ97EBwR2FkzhBRxF5e+jE6LA3yi6Wtc2lyTij1OnDMIr34v5g/tVQtsVAzhT0jc5ygA==}
engines: {node: '>=v14.18.0'}
@@ -5311,6 +5589,14 @@ packages:
- terser
dev: true
/vue-accessible-color-picker@5.0.1(vue@3.3.8):
resolution: {integrity: sha512-IaxDTzW652blWmaNNbqQZzORQAbP19sdO7oJ5fvJIfVizWr2fVV+3z39ORI210Ee7l8YiD5FhpOY/XrToQCBwg==}
peerDependencies:
vue: ^3.2.x
dependencies:
vue: 3.3.8(typescript@5.2.2)
dev: false
/vue-component-type-helpers@1.8.22:
resolution: {integrity: sha512-LK3wJHs3vJxHG292C8cnsRusgyC5SEZDCzDCD01mdE/AoREFMl2tzLRuzwyuEsOIz13tqgBcnvysN3Lxsa14Fw==}
dev: true
@@ -5390,6 +5676,48 @@ packages:
typescript: 5.2.2
dev: true
/vue-types@3.0.2(vue@3.3.8):
resolution: {integrity: sha512-IwUC0Aq2zwaXqy74h4WCvFCUtoV0iSWr0snWnE9TnU18S66GAQyqQbRf2qfJtUuiFsBf6qp0MEwdonlwznlcrw==}
engines: {node: '>=10.15.0'}
peerDependencies:
vue: ^3.0.0
dependencies:
is-plain-object: 3.0.1
vue: 3.3.8(typescript@5.2.2)
dev: false
/vue-types@4.2.1(vue@3.3.8):
resolution: {integrity: sha512-DNQZmJuOvovLUIp0BENRkdnZHbI0V4e2mNvjAZOAXKD56YGvRchtUYOXA/XqTxdv7Ng5SJLZqRKRpAhm5NLaPQ==}
engines: {node: '>=12.16.0'}
peerDependencies:
vue: ^2.0.0 || ^3.0.0
dependencies:
is-plain-object: 5.0.0
vue: 3.3.8(typescript@5.2.2)
dev: false
/vue3-colorpicker@2.2.3(@aesoper/normal-utils@0.1.5)(@popperjs/core@2.11.8)(@vueuse/core@10.6.1)(gradient-parser@1.0.2)(lodash-es@4.17.21)(tinycolor2@1.6.0)(vue-types@4.2.1)(vue@3.3.8):
resolution: {integrity: sha512-hGGH3gfXU8nv7FzSy+xCslOGPCH7YgLxsuY+pQ/GN8SwVZYAd5BXDNt1/8DF+A3wihZ8Whow9XIWwrDhAlJW1Q==}
peerDependencies:
'@aesoper/normal-utils': ^0.1.5
'@popperjs/core': ^2.11.8
'@vueuse/core': ^10.1.2
gradient-parser: ^1.0.2
lodash-es: ^4.17.21
tinycolor2: ^1.4.2
vue: ^3.2.6
vue-types: ^4.1.0
dependencies:
'@aesoper/normal-utils': 0.1.5
'@popperjs/core': 2.11.8
'@vueuse/core': 10.6.1(vue@3.3.8)
gradient-parser: 1.0.2
lodash-es: 4.17.21
tinycolor2: 1.6.0
vue: 3.3.8(typescript@5.2.2)
vue-types: 4.2.1(vue@3.3.8)
dev: false
/vue@3.3.8(typescript@5.2.2):
resolution: {integrity: sha512-5VSX/3DabBikOXMsxzlW8JyfeLKlG9mzqnWgLQLty88vdZL7ZJgrdgBOmrArwxiLtmS+lNNpPcBYqrhE6TQW5w==}
peerDependencies:
@@ -5412,6 +5740,12 @@ packages:
xml-name-validator: 4.0.0
dev: true
/warning@4.0.3:
resolution: {integrity: sha512-rpJyN222KWIvHJ/F53XSZv0Zl/accqHR8et1kpaMTD/fLCRxtV8iX8czMzY7sVZupTI3zcUTg8eycS2kNF9l6w==}
dependencies:
loose-envify: 1.4.0
dev: false
/watchpack@2.4.0:
resolution: {integrity: sha512-Lcvm7MGST/4fup+ifyKi2hjyIAwcdI4HRgtvTpIUxBRhB+RFtUh8XtDOxUfctVCnhVi+QQj49i91OyvzkJl6cg==}
engines: {node: '>=10.13.0'}

View File

@@ -1,4 +1,18 @@
<script setup lang="ts"></script>
<script setup lang="ts">
import { onMounted } from 'vue'
import useStore from '@/store'
import { themeChange } from 'theme-change'
const globalConfig = useStore().globalConfig
const { getTheme: localTheme } = globalConfig
const setLocalTheme=(theme: any)=>{
themeChange(theme.name)
}
onMounted(() => {
setLocalTheme(localTheme)
})
</script>
<template>
<router-view></router-view>

View File

@@ -3,7 +3,7 @@ import { mapActions } from 'pinia';
import { computed } from 'vue';
const props = defineProps({
data: {
type: Array,
type: Array as any,
default: [] as any[]
},
tableColumns: {
@@ -12,16 +12,16 @@ const props= defineProps({
},
})
const dataColumns=computed(()=>{
const dataColumns = computed<any[]>(() => {
// 不带有actions的列
const columns= props.tableColumns.filter(item=>!item.actions)
const columns = props.tableColumns.filter((item: any) => !item.actions)
return columns
})
const actionsColumns=computed(()=>{
const actionsColumns = computed<any[]>(() => {
// 带有actions的列
const columns= props.tableColumns.filter(item=>item.actions)
const columns = props.tableColumns.filter((item: any) => item.actions)
return columns
})
@@ -50,7 +50,8 @@ const actionsColumns=computed(()=>{
</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>
<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>

View File

@@ -8,7 +8,7 @@
<!-- <header class="shadow-2xl head-container h-14">
<Header></Header>
</header> -->
<main class="box-content w-screen h-screen main-container">
<main class="box-content w-screen h-screen overflow-x-hidden overflow-y-auto main-container">
<router-view class="main-container-content"></router-view>
</main>
<!-- <footer class="w-screen footer-container">

View File

@@ -4,6 +4,7 @@ import './style/style.scss'
import * as THREE from 'three';
import App from './App.vue';
const app = createApp(App);
// 全局svg组件
import 'virtual:svg-icons-register';

View File

@@ -87,6 +87,15 @@ export const configRoutes={
title:'图片配置',
icon:'image'
}
},
{
path:'/config/global/music',
name:'MusicConfig',
component:()=>import('@/views/Config/Global/MusicConfig.vue'),
meta:{
title:'音乐配置',
icon:'music'
}
}
]
}

58
src/store/data.ts Normal file
View File

@@ -0,0 +1,58 @@
export const defaultMusicList=[
{
id:'Geoff Knorr - China (The Industrial Era).ogg'+new Date().getTime().toString(),
name:'Geoff Knorr - China (The Industrial Era).ogg',
url:'https://24years.top/resource/audio/Geoff Knorr - China (The Industrial Era).ogg'
},
{
id:'Geoff Knorr&Phill Boucher - China (The Atomic Era).ogg'+new Date().getTime().toString(),
name:'Geoff Knorr&Phill Boucher - China (The Atomic Era).ogg',
url:'https://24years.top/resource/audio/Geoff Knorr&Phill Boucher - China (The Atomic Era).ogg'
},
{
id:'Radetzky March.mp3'+new Date().getTime().toString(),
name:'Radetzky March.mp3',
url:'https://24years.top/resource/audio/Radetzky March.mp3'
},
{
id:'Shanghai.mp3'+new Date().getTime().toString(),
name:'Shanghai.mp3',
url:'https://24years.top/resource/audio/Shanghai.mp3'
},
{
id:'Waltz No.2.mp3'+new Date().getTime().toString(),
name:'Waltz No.2.mp3',
url:'https://24years.top/resource/audio/Waltz No.2.mp3'
},
{
id:'WildChinaTheme.mp3'+new Date().getTime().toString(),
name:'WildChinaTheme.mp3',
url:'https://24years.top/resource/audio/WildChinaTheme.mp3'
},
{
id:'边程&房东的猫 - 美好事物-再遇少年.ogg'+new Date().getTime().toString(),
name:'边程&房东的猫 - 美好事物-再遇少年.ogg',
url:'https://24years.top/resource/audio/边程&房东的猫 - 美好事物-再遇少年.ogg'
},
{
id:'大乔小乔 - 相见难别亦难.ogg'+new Date().getTime().toString(),
name:'大乔小乔 - 相见难别亦难.ogg',
url:'https://24years.top/resource/audio/大乔小乔 - 相见难别亦难.ogg'
},
{
id:'你要跳舞吗-新裤子.mp3'+new Date().getTime().toString(),
name:'你要跳舞吗-新裤子.mp3',
url:'https://24years.top/resource/audio/你要跳舞吗-新裤子.mp3'
},
{
id:'生命-声音玩具.mp3'+new Date().getTime().toString(),
name:'生命-声音玩具.mp3',
url:'https://24years.top/resource/audio/生命-声音玩具.mp3'
},
{
id:'与非门 - Happy New Year.ogg'+new Date().getTime().toString(),
name:'与非门 - Happy New Year.ogg',
url:'https://24years.top/resource/audio/与非门 - Happy New Year.ogg'
},
]

143
src/store/globalConfig.ts Normal file
View File

@@ -0,0 +1,143 @@
import { defineStore } from 'pinia';
import { defaultMusicList } from './data'
// import { IPrizeConfig } from '@/types/prizeConfig';
export const useGlobalConfig = defineStore('global', {
state() {
return {
globalConfig: {
rowCount: 12,
theme: {
name: 'dark',
detail: { primary: '#0f5fd3' },
cardColor: 'rgba(0, 255, 255)',
cardWidth: 140,
cardHeight: 200,
textColor: '#ffffff',
textSize: 30
},
musicList: defaultMusicList,
}
};
},
getters: {
// 获取全部配置
getGlobalConfig(state) {
return state.globalConfig;
},
// 获取行数
getRowCount(state) {
return state.globalConfig.rowCount;
},
// 获取主题
getTheme(state) {
return state.globalConfig.theme;
},
// 获取卡片颜色
getCardColor(state) {
return state.globalConfig.theme.cardColor;
},
// 获取文字颜色
getTextColor(state) {
return state.globalConfig.theme.textColor;
},
// 获取卡片宽高
getCardSize(state) {
return {
width: state.globalConfig.theme.cardWidth,
height: state.globalConfig.theme.cardHeight
}
},
// 获取文字大小
getTextSize(state) {
return state.globalConfig.theme.textSize;
},
// 获取音乐列表
getMusicList(state) {
return state.globalConfig.musicList;
}
},
actions: {
// 设置rowCount
setRowCount(rowCount: number) {
this.globalConfig.rowCount = rowCount;
},
// 设置主题
setTheme(theme: any) {
const { name, detail } = theme;
this.globalConfig.theme.name = name;
this.globalConfig.theme.detail = detail;
},
// 设置卡片颜色
setCardColor(cardColor: string) {
this.globalConfig.theme.cardColor = cardColor;
},
// 设置文字颜色
setTextColor(textColor: string) {
this.globalConfig.theme.textColor = textColor;
},
// 设置卡片宽高
setCardSize(cardSize: { width: number, height: number }) {
this.globalConfig.theme.cardWidth = cardSize.width;
this.globalConfig.theme.cardHeight = cardSize.height;
},
// 设置文字大小
setTextSize(textSize: number) {
this.globalConfig.theme.textSize = textSize;
},
// 添加音乐
addMusic(music: any) {
// 验证音乐是否已存在看name字段
for (let i = 0; i < this.globalConfig.musicList.length; i++) {
if (this.globalConfig.musicList[i].name === music.name) {
return;
}
}
this.globalConfig.musicList.push(music);
},
// 删除音乐
removeMusic(musicId: string) {
for (let i = 0; i < this.globalConfig.musicList.length; i++) {
if (this.globalConfig.musicList[i].id === musicId) {
this.globalConfig.musicList.splice(i, 1);
break;
}
}
},
// 重置音乐列表
resetMusicList() {
this.globalConfig.musicList = defaultMusicList;
},
// 清空音乐列表
clearMusicList() {
this.globalConfig.musicList = [];
},
// 重置所有配置
reset() {
this.globalConfig = {
rowCount: 12,
theme: {
name: 'dark',
detail: { primary: '#0f5fd3' },
cardColor: 'rgba(0, 255, 255)',
cardWidth: 200,
cardHeight: 140,
textColor: '#ffffff',
textSize: 30
},
musicList: defaultMusicList
}
}
},
persist: {
enabled: true,
strategies: [
{
// 如果要存储在localStorage中
storage: localStorage,
key: 'globalConfig',
},
],
},
})

View File

@@ -1,10 +1,12 @@
import { useUserStore } from './user';
import {usePersonConfig} from './personConfig';
import { usePrizeConfig } from './prizeConfig';
import {useGlobalConfig} from './globalConfig';
export default function useStore() {
return {
user: useUserStore(),
personConfig:usePersonConfig(),
prizeConfig:usePrizeConfig()
prizeConfig:usePrizeConfig(),
globalConfig:useGlobalConfig()
};
}

View File

@@ -7,7 +7,7 @@ html {
margin: 0;
padding: 0;
overflow-y: overlay;
overflow: hidden;
overflow-y: hidden;
}
ul {

View File

@@ -1,22 +1,11 @@
.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 {
@@ -24,10 +13,10 @@
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);
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
.card-detail {
@@ -35,7 +24,5 @@
left: 0;
right: 0;
bottom: 15px;
font-size: 12px;
color: rgba(127, 255, 255, 0.75);
}
}

41
src/utils/color.ts Normal file
View File

@@ -0,0 +1,41 @@
// 判断颜色是否rgb或者rgba
export function isRgbOrRgba(color: string) {
return color.indexOf('rgb') > -1 || color.indexOf('rgba') > -1;
}
// 判断是否hex形式
export function isHex(color: string) {
return color.indexOf('#') > -1;
}
// 把hex颜色转成rgb数值类型
export function hexToRgba(hex: string) {
const r = parseInt(hex.slice(1, 3), 16);
const g = parseInt(hex.slice(3, 5), 16);
const b = parseInt(hex.slice(5, 7), 16);
return {r,g,b}
}
// 把rgb数组转化成r g b 数值
export function rgbToRgba(rgb: string) {
const rgbArr = rgb.split('(')[1].split(')')[0].split(',');
return {r:rgbArr[0],g:rgbArr[1],b:rgbArr[2]}
}
// 组成rgb颜色添加透明度
export function rgba(color: string, opacity: number) {
opacity = opacity || 1;
let rgbaStr=''
// 判断是否是hex颜色
if (isHex(color)) {
const {r,g,b} = hexToRgba(color);
rgbaStr = `rgba(${r},${g},${b},${opacity})`
}
else{
const {r,g,b} = rgbToRgba(color)
rgbaStr = `rgba(${r},${g},${b},${opacity})`
}
return rgbaStr
}

View File

@@ -1,4 +1,4 @@
export const readFile = (file: any) => {
export const readFile = (file: any): Promise<any> => {
return new Promise(resolve => {
const reader = new FileReader()
reader.readAsBinaryString(file)
@@ -8,7 +8,18 @@ export const readFile = (file: any) => {
})
}
export const readImage = (file: any) => {
export const readImage = (file: any): Promise<any> => {
return new Promise(resolve => {
const reader = new FileReader()
reader.readAsDataURL(file)
reader.onload = (ev: any) => {
resolve({dataUrl:ev.target.result,fileName:file.name})
}
})
}
export const readMusic = (file: any): Promise<any> => {
return new Promise(resolve => {
const reader = new FileReader()
reader.readAsDataURL(file)

View File

View File

@@ -1,42 +0,0 @@
<script setup lang="ts">
import { reactive } from 'vue';
import { useRouter } from 'vue-router';
const router = useRouter();
const skip = (url: string) => {
router.push({
path: url,
});
};
const formInline = reactive({
user: '',
region: '',
});
const onSubmit = () => {
console.log('submit!');
};
</script>
<template>
<h2>About</h2>
<button @click="skip('/home')">to Home</button>
<el-form :inline="true" :model="formInline" class="demo-form-inline">
<el-form-item label="Approved by">
<el-input v-model="formInline.user" placeholder="Approved by" />
</el-form-item>
<el-form-item label="Activity zone">
<el-select v-model="formInline.region" placeholder="Activity zone">
<el-option label="Zone one" value="shanghai" />
<el-option label="Zone two" value="beijing" />
</el-select>
</el-form-item>
<el-form-item>
<el-button type="primary" @click="onSubmit">Query</el-button>
</el-form-item>
</el-form>
</template>
<style scoped></style>

View File

@@ -1,11 +1,29 @@
<script setup lang='ts'>
import { ref, watch } from 'vue'
import { ref, watch, onMounted } from 'vue'
import useStore from '@/store'
import { themeChange } from 'theme-change';
import zod from 'zod';
import daisyuiThemes from 'daisyui/src/theming/themes'
import { ColorPicker } from 'vue3-colorpicker';
import 'vue3-colorpicker/style.css';
import {isRgbOrRgba,isHex} from '@/utils/color'
const personConfig = useStore().personConfig
const globalConfig = useStore().globalConfig
const { getTheme: localTheme, getCardColor: cardColor,getTextColor:textColor,getCardSize:cardSize,getTextSize: textSize} = globalConfig
const { getTableRowCount: tableRowCount, getShowField } = personConfig
const colorPickerRef = ref()
interface ThemeDaType {
[key: string]: any
}
const themeValue = ref(localTheme.name)
const cardColorValue = ref(cardColor)
const textColorValue = ref(textColor)
const cardSizeValue = ref(cardSize)
const textSizeValue = ref(textSize)
const themeList = ref(Object.keys(daisyuiThemes))
const daisyuiThemeList = ref<ThemeDaType>(daisyuiThemes)
const formData = ref({
rowCount: tableRowCount,
showField: getShowField
@@ -34,18 +52,17 @@ const parseSchema = (props: ValidatePayload) => {
}
const handleChangeShowFields = (fieldItem: any) => {
formData.value.showField.map((item)=>{
if(item.label===fieldItem.label){
item.value=!item.value
}
})
}
// 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)
}
@@ -57,6 +74,30 @@ watch(() => formData.value.rowCount, () => {
watch(() => formData.value.showField, () => {
personConfig.setShowFields(formData.value.showField)
}, { deep: true })
watch(themeValue, (val: any) => {
const selectedThemeDetail = daisyuiThemeList.value[val]
globalConfig.setTheme({ name: val, detail: selectedThemeDetail })
themeChange(val)
if(selectedThemeDetail.primary&&(isHex(selectedThemeDetail.primary)||isRgbOrRgba(selectedThemeDetail.primary))){
globalConfig.setCardColor(selectedThemeDetail.primary)
cardColorValue.value=selectedThemeDetail.primary
}
}, { deep: true })
watch(cardColorValue, (val: string) => {
globalConfig.setCardColor(val)
}, { deep: true })
watch(textColorValue, (val: string) => {
globalConfig.setTextColor(val)
}, { deep: true })
watch(cardSizeValue, (val: { width: number; height: number; }) => {
globalConfig.setCardSize(val)
}, { deep: true })
onMounted(() => {
})
</script>
<template>
@@ -73,16 +114,72 @@ watch(() => formData.value.showField, () => {
</span>
</div>
</label>
<label class="w-full max-w-xs form-control">
<!-- <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)"/>
<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> -->
<label class="w-full max-w-xs form-control">
<div class="label">
<span class="label-text">选择主题</span>
</div>
<select data-choose-theme class="w-full max-w-xs border-solid select border-1" v-model="themeValue">
<option disabled selected>选取主题</option>
<option v-for="(item, index) in themeList" :key="index" :value="item">{{ item }}</option>
</select>
</label>
<label class="w-full max-w-xs form-control">
<div class="label">
<span class="label-text">卡片颜色</span>
</div>
<ColorPicker ref="colorPickerRef" v-model="cardColorValue" v-model:pure-color="cardColorValue"></ColorPicker>
</label>
<label class="w-full max-w-xs form-control">
<div class="label">
<span class="label-text">文字颜色</span>
</div>
<ColorPicker ref="colorPickerRef" v-model="textColorValue" v-model:pure-color="textColorValue"></ColorPicker>
</label>
<label class="flex flex-row w-full max-w-xs gap-10 mb-10 form-control">
<div>
<div class="label">
<span class="label-text">卡片宽度</span>
</div>
<input type="number" v-model="cardSizeValue.width" 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>
</div>
<div>
<div class="label">
<span class="label-text">卡片高度</span>
</div>
<input type="number" v-model="cardSizeValue.height" 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>
</div>
</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="textSizeValue" placeholder="Type here"
class="w-full max-w-xs input input-bordered" />
</label>
</div>
</template>

View File

@@ -20,6 +20,7 @@ const handleFileChange = async (e: any) => {
imageDbStore.setItem(new Date().getTime().toString() + '+' + fileName, dataUrl)
.then(() => {
imgUploadToast.value = 1
getImageDbStore()
})
.catch(() => {
imgUploadToast.value = 2
@@ -27,6 +28,7 @@ const handleFileChange = async (e: any) => {
}
const getImageDbStore =async () => {
imgList.value = []
const keys =await imageDbStore.keys()
if(keys.length>0){
imageDbStore.iterate((value, key) => {
@@ -75,7 +77,7 @@ watch(() => imgUploadToast.value, (val) => {
<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">
<div class="w-12 h-12 mask mask-squircle">
<img :src="item.value" alt="Avatar Tailwind CSS Component" />
</div>
</div>

View File

@@ -0,0 +1,119 @@
<script setup lang='ts'>
import { ref, onMounted } from 'vue'
import { readMusic } from '@/utils/file'
import useStore from '@/store';
import localforage from 'localforage'
const audioUploadToast = ref(0) //0是不显示1是成功2是失败,3是不是图片
const audioDbStore = localforage.createInstance({
name: 'audioStore'
})
const globalConfig = useStore().globalConfig
const { getMusicList: localMusicList } = globalConfig;
const audio = ref(new Audio())
const limitType = ref('audio/*')
const localMusicListValue = ref(localMusicList)
const play = async (item: any) => {
let audioUrl = ''
if (!item.url) {
return
}
if (item.url == 'Storage') {
audioUrl = await audioDbStore.getItem(item.name) as string
}
else {
audioUrl = item.url
}
audio.value.pause()
audio.value.src = audioUrl
audio.value.currentTime = 0
audio.value.play()
}
const pausePlay = () => {
audio.value.pause()
}
const deleteMusic = (item: any) => {
globalConfig.removeMusic(item.id)
audioDbStore.removeItem(item.name)
// setTimeout(()=>{
// localMusicListValue.value=localMusicList
// },100)
}
const resetMusic = () => {
globalConfig.resetMusicList()
audioDbStore.clear()
}
const deleteAll = () => {
globalConfig.clearMusicList()
audioDbStore.clear()
localMusicListValue.value = []
}
const getMusicDbStore = async () => {
const keys = await audioDbStore.keys()
if (keys.length > 0) {
audioDbStore.iterate((value: string, key: string) => {
globalConfig.addMusic({
id: key + new Date().getTime().toString(),
name: key,
url: 'Storage',
})
})
}
}
const handleFileChange = async (e: any) => {
const isAudio = /audio*/.test(e.target.files[0].type)
if (!isAudio) {
audioUploadToast.value = 3
return
}
let { dataUrl, fileName } = await readMusic(e.target.files[0])
audioDbStore.setItem(new Date().getTime().toString() + '+' + fileName, dataUrl)
.then(() => {
audioUploadToast.value = 1
getMusicDbStore()
})
.catch(() => {
audioUploadToast.value = 2
})
}
onMounted(() => {
getMusicDbStore()
})
</script>
<template>
<div>
<div class="flex gap-3">
<button class="btn btn-primary btn-xs" @click="resetMusic">重置音乐列表</button>
<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-xs" @click="pausePlay">暂停播放</button>
<button class="btn btn-error btn-xs" @click="deleteAll">删除所有</button>
</div>
<div>
<ul>
<li v-for="item in localMusicListValue" :key="item.id" class="flex items-center gap-6 pb-2 mb-3 divide-y">
<div class="mr-12 overflow-hidden w-72 whitespace-nowrap text-ellipsis">
<span>
{{ item.name }}</span>
</div>
<div class="flex gap-3">
<button class="btn btn-primary btn-xs" @click="play(item)">播放</button>
<button class="btn btn-error btn-xs" @click="deleteMusic(item)">删除</button>
</div>
</li>
</ul>
</div>
</div>
</template>
<style lang='scss' scoped></style>

View File

@@ -6,8 +6,6 @@ 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
@@ -23,9 +21,7 @@ const handleFileChange = async (e: any) => {
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)
}
@@ -98,7 +94,7 @@ const tableColumns = [
</script>
<template>
<div class="overflow-y-auto">
<div class="">
<div class="flex justify-center gap-3">
<button class="btn btn-error btn-sm" @click="deleteAll">全部删除</button>
<div class="">

View File

@@ -52,7 +52,6 @@ onMounted(() => {
getImageDbStore()
})
watch(()=>prizeList,()=>{
console.log('prizeList',prizeList.value)
prizeConfig.setPrizeConfig(prizeList.value)
},{deep:true})
</script>
@@ -65,22 +64,22 @@ watch(()=>prizeList,()=>{
<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>
<svg-icon class="cursor-pointer hover:text-blue-400" :class="prizeList.indexOf(item)==0?'opacity-0 cursor-default':''" name="up" @click="sort(item,1)"></svg-icon>
<svg-icon class="cursor-pointer hover:text-blue-400" 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" />
<input type="text" v-model="item.name" 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>
<input type="checkbox" :checked="item.isAll" @change="item.isAll =!item.isAll"
class="checkbox checkbox-secondary border-1 border-solid mt-2" />
class="mt-2 border-solid checkbox checkbox-secondary border-1" />
</label>
<label class="w-full max-w-xs mb-10 form-control">
<div class="label">
@@ -93,7 +92,7 @@ watch(()=>prizeList,()=>{
<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">
<select class="w-full max-w-xs select select-warning select-sm" v-model="item.picture">
<option disabled selected>选择一张图片</option>
<option v-for="picItem in imgList" :key="picItem.key">{{ picItem.key.split('+')[1] }}</option>
</select>
@@ -103,7 +102,7 @@ watch(()=>prizeList,()=>{
<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" />
class="mt-2 border-solid checkbox checkbox-secondary border-1" />
</label>
</li>
</ul>

View File

@@ -1,10 +1,12 @@
<script setup lang="ts">
import { ref,onMounted } from 'vue';
import { useRouter } from 'vue-router';
import { ref } from 'vue';
import { useRouter, useRoute } from 'vue-router';
import { configRoutes } from '../../router';
const router = useRouter();
const menuList = ref(configRoutes.children);
const route = useRoute();
const menuList = ref<any[]>(configRoutes.children)
const cleanMenuList = (menu: any) => {
const newList = menu;
@@ -20,38 +22,78 @@ const cleanMenuList=(menu:any)=>{
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">
<div class="flex min-h-[calc(100%-260px)]">
<ul class="w-56 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>
<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>
<a @click="skip(subItem.path)"
:style="subSubItem.name == route.name ? 'background-color:rgba(12,12,12,0.2)' : ''">{{
subSubItem.meta!.title }}</a>
</li>
</ul>
</details>
<a v-else @click="skip(subItem.path)">{{ subItem.meta!.title }}</a>
<a v-else @click="skip(subItem.path)"
:style="subItem.name == route.name ? 'background-color:rgba(12,12,12,0.2)' : ''">{{
subItem.meta!.title }}</a>
</li>
</ul>
</details>
<a v-else @click="skip(item.path)">{{ item.meta!.title }}</a>
<a v-else @click="skip(item.path)"
:style="item.name == route.name ? 'background-color:rgba(12,12,12,0.2)' : ''">{{ item.meta!.title }}</a>
</li>
</ul>
<router-view></router-view>
</div>
</template>
<footer class="p-10 rounded footer footer-center bg-base-200 text-base-content">
<nav class="grid grid-flow-col gap-4">
<a class="link link-hover">About us</a>
<a class="link link-hover">Contact</a>
<a class="link link-hover">Jobs</a>
<a class="link link-hover">Press kit</a>
</nav>
<nav>
<div class="grid grid-flow-col gap-4">
<a><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"
class="fill-current">
<path
d="M24 4.557c-.883.392-1.832.656-2.828.775 1.017-.609 1.798-1.574 2.165-2.724-.951.564-2.005.974-3.127 1.195-.897-.957-2.178-1.555-3.594-1.555-3.179 0-5.515 2.966-4.797 6.045-4.091-.205-7.719-2.165-10.148-5.144-1.29 2.213-.669 5.108 1.523 6.574-.806-.026-1.566-.247-2.229-.616-.054 2.281 1.581 4.415 3.949 4.89-.693.188-1.452.232-2.224.084.626 1.956 2.444 3.379 4.6 3.419-2.07 1.623-4.678 2.348-7.29 2.04 2.179 1.397 4.768 2.212 7.548 2.212 9.142 0 14.307-7.721 13.995-14.646.962-.695 1.797-1.562 2.457-2.549z">
</path>
</svg></a>
<a><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"
class="fill-current">
<path
d="M19.615 3.184c-3.604-.246-11.631-.245-15.23 0-3.897.266-4.356 2.62-4.385 8.816.029 6.185.484 8.549 4.385 8.816 3.6.245 11.626.246 15.23 0 3.897-.266 4.356-2.62 4.385-8.816-.029-6.185-.484-8.549-4.385-8.816zm-10.615 12.816v-8l8 3.993-8 4.007z">
</path>
</svg></a>
<a><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"
class="fill-current">
<path
d="M9 8h-3v4h3v12h5v-12h3.642l.358-4h-4v-1.667c0-.955.192-1.333 1.115-1.333h2.885v-5h-3.808c-3.596 0-5.192 1.583-5.192 4.615v3.385z">
</path>
</svg></a>
</div>
</nav>
<aside>
<p>Copyright © 2024 - All right reserved by ACME Industries Ltd</p>
</aside>
</footer></template>
<style scoped></style>

View File

@@ -0,0 +1,75 @@
<script setup lang='ts'>
import { ref, onMounted, onUnmounted } from 'vue'
import useStore from '@/store';
import localforage from 'localforage'
const audioDbStore = localforage.createInstance({
name: 'audioStore'
})
const audio = ref(new Audio())
const currentMusic = ref<any>()
const globalConfig = useStore().globalConfig
const { getMusicList: localMusicList } = globalConfig;
const localMusicListValue = ref(localMusicList)
const play = async (item: any,skip=false) => {
if (!audio.value.paused&&!skip) {
audio.value.pause()
return
}
let audioUrl = ''
if (!item.url) {
return
}
if (item.url == 'Storage') {
audioUrl = await audioDbStore.getItem(item.name) as string
}
else {
audioUrl = item.url
}
audio.value.pause()
audio.value.src = audioUrl
audio.value.currentTime = 0
audio.value.play()
}
const nextPlay = () => {
// 播放下一首
if (localMusicListValue.value.length > 1) {
let index = localMusicListValue.value.findIndex((item: any) => item.name == currentMusic.value.name)
index++
if (index >= localMusicListValue.value.length) {
index = 0
}
currentMusic.value = localMusicListValue.value[index]
play(currentMusic.value,true)
}
}
// 监听播放成后开始下一首
const onPlayEnd = () => {
audio.value.addEventListener('ended', nextPlay)
}
onMounted(() => {
currentMusic.value = localMusicListValue.value[0]
onPlayEnd()
})
onUnmounted(() => {
audio.value.removeEventListener('ended', nextPlay)
})
</script>
<template>
<div class="flex gap-3">
<div class="bg-red-300 cursor-pointer" @click="play(currentMusic)">
播放/暂停
</div>
<div class="bg-blue-300 cursor-pointer" @click="nextPlay">下一首</div>
</div>
</template>
<style lang='scss' scoped></style>

View File

@@ -0,0 +1,16 @@
<script setup lang='ts'>
import useStore from '@/store'
const prizeConfig = useStore().prizeConfig
</script>
<template>
<div>
List
</div>
</template>
<style lang='scss' scoped>
</style>

View File

@@ -1,6 +1,8 @@
<script setup lang="ts">
import { ref, onMounted } from 'vue'
// import { tableData2 as tableData } from './data'
import {rgba} from '@/utils/color'
import PlayMusic from './PlayMusic.vue'
import * as THREE from 'three'
import {
CSS3DRenderer, CSS3DObject
@@ -10,7 +12,11 @@ import TWEEN from 'three/examples/jsm/libs/tween.module.js';
import useStore from '@/store'
const personConfig=useStore().personConfig
const globalConfig=useStore().globalConfig
// const globalConfig = useStore().globalConfig
const {getAlreadyPersonList:alreadyPersonList,getNotPersonList:notPersonList,getTableRowCount:rowCount}=personConfig
const {getCardColor:cardColor,getTextColor:textColor,getCardSize:cardSize,getTextSize:textSize} = globalConfig
const tableData=ref(
alreadyPersonList.concat(notPersonList)
)
@@ -59,22 +65,42 @@ const init = () => {
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} )`;
// element.style.backgroundColor = `rgba( 0, 127, 127, ${Math.random() * 0.5 + 0.25} )`;
element.style.backgroundColor = rgba(cardColor,Math.random() * 0.5 + 0.25)
element.style.border=`1px solid ${rgba(cardColor,0.25)}`
element.style.boxShadow=`0 0 12px ${rgba(cardColor,0.5)}`
// hover style
element.addEventListener('mouseover', function () {
this.style.border=`1px solid ${rgba(cardColor,0.75)}`
this.style.boxShadow=`0 0 12px ${rgba(cardColor,0.75)}`
})
element.addEventListener('mouseout', function () {
this.style.border=`1px solid ${rgba(cardColor,0.25)}`
this.style.boxShadow=`0 0 12px ${rgba(cardColor,0.5)}`
})
element.style.width = `${cardSize.width}px`;
element.style.height = `${cardSize.height}px`;
// element.style.color=localTheme.detail.primary
const number = document.createElement('div');
number.className = 'card-id';
// number.textContent = (i / 5 + 1).toString();
number.textContent = tableData.value[i].uid;
number.style.fontSize = `${textSize*0.5}px`;
element.appendChild(number);
const symbol = document.createElement('div');
symbol.className = 'card-name';
symbol.textContent = tableData.value[i].name;
symbol.style.textShadow=`0 0 12px ${rgba(cardColor,0.95)}`
symbol.style.fontSize = `${textSize}px`;
element.appendChild(symbol);
const detail = document.createElement('div');
detail.className = 'card-detail';
detail.innerHTML = `${tableData.value[i].department}<br/>${tableData.value[i].other}`;
detail.style.fontSize = `${textSize*0.5}px`;
element.appendChild(detail);
const object = new CSS3DObject(element);
@@ -96,8 +122,8 @@ const init = () => {
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.x = tableData.value[i].x * (cardSize.width+40) - rowCount*90;
object.position.y = -tableData.value[i].y *(cardSize.height+20) + 1000;
object.position.z = 0;
targets.table.push(object);
@@ -204,6 +230,7 @@ function render() {
onMounted(() => {
init();
animation();
containerRef.value!.style.color=`${textColor}`
});
</script>
@@ -218,6 +245,7 @@ onMounted(() => {
</div>
<!-- end -->
</div>
<PlayMusic class="absolute bottom-10 right-10"></PlayMusic>
</template>
<style scoped lang="scss">

View File

@@ -6,17 +6,15 @@ module.exports = {
},
content: ['./index.html', './src/**/*.{vue,js,ts,jsx,tsx}'],
plugins: [require('@tailwindcss/typography'), require('daisyui')],
theme: {
extend: {
colors: {
bg_color: 'var(--el-bg-color)',
primary: 'var(--el-color-primary)',
primary_light_9: 'var(--el-color-primary-light-9)',
text_color_primary: 'var(--el-text-color-primary)',
text_color_regular: 'var(--el-text-color-regular)',
text_color_disabled: 'var(--el-text-color-disabled)'
}
}
}
daisyui: {
themes: true, // false: only light + dark | true: all themes | array: specific themes like this ["light", "dark", "cupcake"]
darkTheme: 'dark', // name of one of the included themes for dark mode
base: true, // applies background color and foreground color for root element by default
styled: true, // include daisyUI colors and design decisions for all components
utils: true, // adds responsive and modifier utility classes
prefix: '', // prefix for daisyUI classnames (components, modifiers and responsive class names. Not colors)
logs: true, // Shows info about daisyUI version and used config in the console when building your CSS
themeRoot: ':root', // The element that receives theme color CSS variables
},
};