Compare commits
2 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 922b4dd83f | |||
| 4ed4ba35b6 |
461
package-lock.json
generated
461
package-lock.json
generated
@@ -24,15 +24,12 @@
|
|||||||
"@vue/cli-plugin-router": "~5.0.0",
|
"@vue/cli-plugin-router": "~5.0.0",
|
||||||
"@vue/cli-plugin-vuex": "~5.0.0",
|
"@vue/cli-plugin-vuex": "~5.0.0",
|
||||||
"@vue/cli-service": "~5.0.0",
|
"@vue/cli-service": "~5.0.0",
|
||||||
"autoprefixer": "^10.4.24",
|
|
||||||
"less": "^4.2.2",
|
"less": "^4.2.2",
|
||||||
"less-loader": "^12.2.0",
|
"less-loader": "^12.2.0",
|
||||||
"postcss": "^8.5.6",
|
|
||||||
"postcss-preset-env": "^10.1.5",
|
"postcss-preset-env": "^10.1.5",
|
||||||
"postcss-px-to-viewport": "^1.1.1",
|
"postcss-px-to-viewport": "^1.1.1",
|
||||||
"postcss-px-viewport": "^0.0.4",
|
"postcss-px-viewport": "^0.0.4",
|
||||||
"postcss-viewport-units": "^0.1.6",
|
"postcss-viewport-units": "^0.1.6"
|
||||||
"tailwindcss": "^3.4.17"
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@achrinza/node-ipc": {
|
"node_modules/@achrinza/node-ipc": {
|
||||||
@@ -50,19 +47,6 @@
|
|||||||
"node": "8 || 9 || 10 || 11 || 12 || 13 || 14 || 15 || 16 || 17 || 18 || 19 || 20 || 21 || 22"
|
"node": "8 || 9 || 10 || 11 || 12 || 13 || 14 || 15 || 16 || 17 || 18 || 19 || 20 || 21 || 22"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@alloc/quick-lru": {
|
|
||||||
"version": "5.2.0",
|
|
||||||
"resolved": "https://registry.npmmirror.com/@alloc/quick-lru/-/quick-lru-5.2.0.tgz",
|
|
||||||
"integrity": "sha512-UrcABB+4bUrFABwbluTIBErXwvbsU/V7TZWfmbgJfbkwiBuziS9gxdODUyuiecfdGQ85jglMW6juS3+z5TsKLw==",
|
|
||||||
"dev": true,
|
|
||||||
"license": "MIT",
|
|
||||||
"engines": {
|
|
||||||
"node": ">=10"
|
|
||||||
},
|
|
||||||
"funding": {
|
|
||||||
"url": "https://github.com/sponsors/sindresorhus"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/@ampproject/remapping": {
|
"node_modules/@ampproject/remapping": {
|
||||||
"version": "2.3.0",
|
"version": "2.3.0",
|
||||||
"resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.3.0.tgz",
|
"resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.3.0.tgz",
|
||||||
@@ -4598,13 +4582,6 @@
|
|||||||
],
|
],
|
||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
"node_modules/arg": {
|
|
||||||
"version": "5.0.2",
|
|
||||||
"resolved": "https://registry.npmmirror.com/arg/-/arg-5.0.2.tgz",
|
|
||||||
"integrity": "sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg==",
|
|
||||||
"dev": true,
|
|
||||||
"license": "MIT"
|
|
||||||
},
|
|
||||||
"node_modules/array-flatten": {
|
"node_modules/array-flatten": {
|
||||||
"version": "1.1.1",
|
"version": "1.1.1",
|
||||||
"resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz",
|
"resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz",
|
||||||
@@ -4652,9 +4629,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/autoprefixer": {
|
"node_modules/autoprefixer": {
|
||||||
"version": "10.4.24",
|
"version": "10.4.21",
|
||||||
"resolved": "https://registry.npmmirror.com/autoprefixer/-/autoprefixer-10.4.24.tgz",
|
"resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.4.21.tgz",
|
||||||
"integrity": "sha512-uHZg7N9ULTVbutaIsDRoUkoS8/h3bdsmVJYZ5l3wv8Cp/6UIIoRDm90hZ+BwxUj/hGBEzLxdHNSKuFpn8WOyZw==",
|
"integrity": "sha512-O+A6LWV5LDHSJD3LjHYoNi4VLsj/Whi7k6zG12xTYaU4cQ8oxQGckXNX8cRHK5yOZ/ppVHe0ZBXGzSV9jXdVbQ==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"funding": [
|
"funding": [
|
||||||
{
|
{
|
||||||
@@ -4672,9 +4649,10 @@
|
|||||||
],
|
],
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"browserslist": "^4.28.1",
|
"browserslist": "^4.24.4",
|
||||||
"caniuse-lite": "^1.0.30001766",
|
"caniuse-lite": "^1.0.30001702",
|
||||||
"fraction.js": "^5.3.4",
|
"fraction.js": "^4.3.7",
|
||||||
|
"normalize-range": "^0.1.2",
|
||||||
"picocolors": "^1.1.1",
|
"picocolors": "^1.1.1",
|
||||||
"postcss-value-parser": "^4.2.0"
|
"postcss-value-parser": "^4.2.0"
|
||||||
},
|
},
|
||||||
@@ -4814,16 +4792,6 @@
|
|||||||
],
|
],
|
||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
"node_modules/baseline-browser-mapping": {
|
|
||||||
"version": "2.9.19",
|
|
||||||
"resolved": "https://registry.npmmirror.com/baseline-browser-mapping/-/baseline-browser-mapping-2.9.19.tgz",
|
|
||||||
"integrity": "sha512-ipDqC8FrAl/76p2SSWKSI+H9tFwm7vYqXQrItCuiVPt26Km0jS+NzSsBWAaBusvSbQcfJG+JitdMm+wZAgTYqg==",
|
|
||||||
"dev": true,
|
|
||||||
"license": "Apache-2.0",
|
|
||||||
"bin": {
|
|
||||||
"baseline-browser-mapping": "dist/cli.js"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/batch": {
|
"node_modules/batch": {
|
||||||
"version": "0.6.1",
|
"version": "0.6.1",
|
||||||
"resolved": "https://registry.npmjs.org/batch/-/batch-0.6.1.tgz",
|
"resolved": "https://registry.npmjs.org/batch/-/batch-0.6.1.tgz",
|
||||||
@@ -4967,9 +4935,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/browserslist": {
|
"node_modules/browserslist": {
|
||||||
"version": "4.28.1",
|
"version": "4.24.4",
|
||||||
"resolved": "https://registry.npmmirror.com/browserslist/-/browserslist-4.28.1.tgz",
|
"resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.24.4.tgz",
|
||||||
"integrity": "sha512-ZC5Bd0LgJXgwGqUknZY/vkUQ04r8NXnJZ3yYi4vDmSiZmC/pdSN0NbNRPxZpbtO4uAfDUAFffO8IZoM3Gj8IkA==",
|
"integrity": "sha512-KDi1Ny1gSePi1vm0q4oxSF8b4DR44GF4BbmS2YdhPLOEqd8pDviZOGH/GsmRwoWJ2+5Lr085X7naowMwKHDG1A==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"funding": [
|
"funding": [
|
||||||
{
|
{
|
||||||
@@ -4987,11 +4955,10 @@
|
|||||||
],
|
],
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"baseline-browser-mapping": "^2.9.0",
|
"caniuse-lite": "^1.0.30001688",
|
||||||
"caniuse-lite": "^1.0.30001759",
|
"electron-to-chromium": "^1.5.73",
|
||||||
"electron-to-chromium": "^1.5.263",
|
"node-releases": "^2.0.19",
|
||||||
"node-releases": "^2.0.27",
|
"update-browserslist-db": "^1.1.1"
|
||||||
"update-browserslist-db": "^1.2.0"
|
|
||||||
},
|
},
|
||||||
"bin": {
|
"bin": {
|
||||||
"browserslist": "cli.js"
|
"browserslist": "cli.js"
|
||||||
@@ -5122,16 +5089,6 @@
|
|||||||
"node": ">=6"
|
"node": ">=6"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/camelcase-css": {
|
|
||||||
"version": "2.0.1",
|
|
||||||
"resolved": "https://registry.npmmirror.com/camelcase-css/-/camelcase-css-2.0.1.tgz",
|
|
||||||
"integrity": "sha512-QOSvevhslijgYwRx6Rv7zKdMF8lbRmx+uQGx2+vDc+KI/eBnsy9kit5aj23AgGu3pa4t9AgwbnXWqS+iOY+2aA==",
|
|
||||||
"dev": true,
|
|
||||||
"license": "MIT",
|
|
||||||
"engines": {
|
|
||||||
"node": ">= 6"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/caniuse-api": {
|
"node_modules/caniuse-api": {
|
||||||
"version": "3.0.0",
|
"version": "3.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/caniuse-api/-/caniuse-api-3.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/caniuse-api/-/caniuse-api-3.0.0.tgz",
|
||||||
@@ -5146,9 +5103,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/caniuse-lite": {
|
"node_modules/caniuse-lite": {
|
||||||
"version": "1.0.30001767",
|
"version": "1.0.30001707",
|
||||||
"resolved": "https://registry.npmmirror.com/caniuse-lite/-/caniuse-lite-1.0.30001767.tgz",
|
"resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001707.tgz",
|
||||||
"integrity": "sha512-34+zUAMhSH+r+9eKmYG+k2Rpt8XttfE4yXAjoZvkAPs15xcYQhyBYdalJ65BzivAvGRMViEjy6oKr/S91loekQ==",
|
"integrity": "sha512-3qtRjw/HQSMlDWf+X79N206fepf4SOOU6SQLMaq/0KkZLmSjPxAkBOQQ+FxbHKfHmYLZFfdWsO3KA90ceHPSnw==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"funding": [
|
"funding": [
|
||||||
{
|
{
|
||||||
@@ -6428,13 +6385,6 @@
|
|||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
"node_modules/didyoumean": {
|
|
||||||
"version": "1.2.2",
|
|
||||||
"resolved": "https://registry.npmmirror.com/didyoumean/-/didyoumean-1.2.2.tgz",
|
|
||||||
"integrity": "sha512-gxtyfqMg7GKyhQmb056K7M3xszy/myH8w+B4RT+QXBQsvAOdc3XymqDDPHx1BgPgsdAA5SIifona89YtRATDzw==",
|
|
||||||
"dev": true,
|
|
||||||
"license": "Apache-2.0"
|
|
||||||
},
|
|
||||||
"node_modules/dir-glob": {
|
"node_modules/dir-glob": {
|
||||||
"version": "3.0.1",
|
"version": "3.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz",
|
||||||
@@ -6448,13 +6398,6 @@
|
|||||||
"node": ">=8"
|
"node": ">=8"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/dlv": {
|
|
||||||
"version": "1.1.3",
|
|
||||||
"resolved": "https://registry.npmmirror.com/dlv/-/dlv-1.1.3.tgz",
|
|
||||||
"integrity": "sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA==",
|
|
||||||
"dev": true,
|
|
||||||
"license": "MIT"
|
|
||||||
},
|
|
||||||
"node_modules/dns-packet": {
|
"node_modules/dns-packet": {
|
||||||
"version": "5.6.1",
|
"version": "5.6.1",
|
||||||
"resolved": "https://registry.npmjs.org/dns-packet/-/dns-packet-5.6.1.tgz",
|
"resolved": "https://registry.npmjs.org/dns-packet/-/dns-packet-5.6.1.tgz",
|
||||||
@@ -6630,9 +6573,9 @@
|
|||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
"node_modules/electron-to-chromium": {
|
"node_modules/electron-to-chromium": {
|
||||||
"version": "1.5.283",
|
"version": "1.5.129",
|
||||||
"resolved": "https://registry.npmmirror.com/electron-to-chromium/-/electron-to-chromium-1.5.283.tgz",
|
"resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.129.tgz",
|
||||||
"integrity": "sha512-3vifjt1HgrGW/h76UEeny+adYApveS9dH2h3p57JYzBSXJIKUJAvtmIytDKjcSCt9xHfrNCFJ7gts6vkhuq++w==",
|
"integrity": "sha512-JlXUemX4s0+9f8mLqib/bHH8gOHf5elKS6KeWG3sk3xozb/JTq/RLXIv8OKUWiK4Ah00Wm88EFj5PYkFr4RUPA==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "ISC"
|
"license": "ISC"
|
||||||
},
|
},
|
||||||
@@ -7254,16 +7197,16 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/fraction.js": {
|
"node_modules/fraction.js": {
|
||||||
"version": "5.3.4",
|
"version": "4.3.7",
|
||||||
"resolved": "https://registry.npmmirror.com/fraction.js/-/fraction.js-5.3.4.tgz",
|
"resolved": "https://registry.npmjs.org/fraction.js/-/fraction.js-4.3.7.tgz",
|
||||||
"integrity": "sha512-1X1NTtiJphryn/uLQz3whtY6jK3fTqoE3ohKs0tT+Ujr1W59oopxmoEh7Lu5p6vBaPbgoM0bzveAW4Qi5RyWDQ==",
|
"integrity": "sha512-ZsDfxO51wGAXREY55a7la9LScWpwv9RxIrYABrlvOFBlH/ShPnrtsXeuUIfXKKOVicNxQ+o8JTbJvjS4M89yew==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": "*"
|
"node": "*"
|
||||||
},
|
},
|
||||||
"funding": {
|
"funding": {
|
||||||
"type": "github",
|
"type": "patreon",
|
||||||
"url": "https://github.com/sponsors/rawify"
|
"url": "https://github.com/sponsors/rawify"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -8255,16 +8198,6 @@
|
|||||||
"url": "https://github.com/chalk/supports-color?sponsor=1"
|
"url": "https://github.com/chalk/supports-color?sponsor=1"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/jiti": {
|
|
||||||
"version": "1.21.7",
|
|
||||||
"resolved": "https://registry.npmmirror.com/jiti/-/jiti-1.21.7.tgz",
|
|
||||||
"integrity": "sha512-/imKNG4EbWNrVjoNC/1H5/9GFy+tqjGBHCaSsN+P2RnPqjsLmv6UD3Ej+Kj8nBWaRAwyk7kK5ZUc+OEatnTR3A==",
|
|
||||||
"dev": true,
|
|
||||||
"license": "MIT",
|
|
||||||
"bin": {
|
|
||||||
"jiti": "bin/jiti.js"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/joi": {
|
"node_modules/joi": {
|
||||||
"version": "17.13.3",
|
"version": "17.13.3",
|
||||||
"resolved": "https://registry.npmjs.org/joi/-/joi-17.13.3.tgz",
|
"resolved": "https://registry.npmjs.org/joi/-/joi-17.13.3.tgz",
|
||||||
@@ -9293,9 +9226,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/node-releases": {
|
"node_modules/node-releases": {
|
||||||
"version": "2.0.27",
|
"version": "2.0.19",
|
||||||
"resolved": "https://registry.npmmirror.com/node-releases/-/node-releases-2.0.27.tgz",
|
"resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.19.tgz",
|
||||||
"integrity": "sha512-nmh3lCkYZ3grZvqcCH+fjmQ7X+H0OeZgP40OierEaAptX4XofMh5kwNbWh7lBduUzCcV/8kZ+NDLCwm2iorIlA==",
|
"integrity": "sha512-xxOWJsBKtzAq7DY0J+DTzuz58K8e7sJbdgwkbMWQe8UYB6ekmsQ45q0M/tJDsGaZmbC+l7n57UV8Hl5tHxO9uw==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
@@ -9332,6 +9265,16 @@
|
|||||||
"node": ">=0.10.0"
|
"node": ">=0.10.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/normalize-range": {
|
||||||
|
"version": "0.1.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/normalize-range/-/normalize-range-0.1.2.tgz",
|
||||||
|
"integrity": "sha512-bdok/XvKII3nUpklnV6P2hxtMNrCboOjAcyBuQnWEhO665FwrSNRxU+AqpsyvO6LgGYPspN+lu5CLtw4jPRKNA==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=0.10.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/normalize-url": {
|
"node_modules/normalize-url": {
|
||||||
"version": "6.1.0",
|
"version": "6.1.0",
|
||||||
"resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-6.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-6.1.0.tgz",
|
||||||
@@ -9387,16 +9330,6 @@
|
|||||||
"node": ">=0.10.0"
|
"node": ">=0.10.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/object-hash": {
|
|
||||||
"version": "3.0.0",
|
|
||||||
"resolved": "https://registry.npmmirror.com/object-hash/-/object-hash-3.0.0.tgz",
|
|
||||||
"integrity": "sha512-RSn9F68PjH9HqtltsSnqYC1XXoWe9Bju5+213R98cNGttag9q9yAOTzdbsqvIa7aNm5WffBZFpWYr2aWrklWAw==",
|
|
||||||
"dev": true,
|
|
||||||
"license": "MIT",
|
|
||||||
"engines": {
|
|
||||||
"node": ">= 6"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/object-inspect": {
|
"node_modules/object-inspect": {
|
||||||
"version": "1.13.4",
|
"version": "1.13.4",
|
||||||
"resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.4.tgz",
|
"resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.4.tgz",
|
||||||
@@ -9847,16 +9780,6 @@
|
|||||||
"@vue/devtools-kit": "^7.7.2"
|
"@vue/devtools-kit": "^7.7.2"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/pirates": {
|
|
||||||
"version": "4.0.7",
|
|
||||||
"resolved": "https://registry.npmmirror.com/pirates/-/pirates-4.0.7.tgz",
|
|
||||||
"integrity": "sha512-TfySrs/5nm8fQJDcBDuUng3VOUKsd7S+zqvbOTiGXHfxX4wK31ard+hoNuvkicM/2YFzlpDgABOevKSsB4G/FA==",
|
|
||||||
"dev": true,
|
|
||||||
"license": "MIT",
|
|
||||||
"engines": {
|
|
||||||
"node": ">= 6"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/pkg-dir": {
|
"node_modules/pkg-dir": {
|
||||||
"version": "4.2.0",
|
"version": "4.2.0",
|
||||||
"resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz",
|
"resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz",
|
||||||
@@ -9885,9 +9808,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/postcss": {
|
"node_modules/postcss": {
|
||||||
"version": "8.5.6",
|
"version": "8.5.3",
|
||||||
"resolved": "https://registry.npmmirror.com/postcss/-/postcss-8.5.6.tgz",
|
"resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.3.tgz",
|
||||||
"integrity": "sha512-3Ybi1tAuwAP9s0r1UQ2J4n5Y0G05bJkpUIO0/bI9MhwmD70S5aTWbXGBwxHrelT+XM1k6dM0pk+SwNkpTRN7Pg==",
|
"integrity": "sha512-dle9A3yYxlBSrt8Fu+IpjGT8SY8hN0mlaA6GY8t0P5PjIOZemULz/E2Bnm/2dcUOena75OTNkHI76uZBNUUq3A==",
|
||||||
"funding": [
|
"funding": [
|
||||||
{
|
{
|
||||||
"type": "opencollective",
|
"type": "opencollective",
|
||||||
@@ -9904,7 +9827,7 @@
|
|||||||
],
|
],
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"nanoid": "^3.3.11",
|
"nanoid": "^3.3.8",
|
||||||
"picocolors": "^1.1.1",
|
"picocolors": "^1.1.1",
|
||||||
"source-map-js": "^1.2.1"
|
"source-map-js": "^1.2.1"
|
||||||
},
|
},
|
||||||
@@ -10464,50 +10387,6 @@
|
|||||||
"postcss": "^8.4"
|
"postcss": "^8.4"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/postcss-import": {
|
|
||||||
"version": "15.1.0",
|
|
||||||
"resolved": "https://registry.npmmirror.com/postcss-import/-/postcss-import-15.1.0.tgz",
|
|
||||||
"integrity": "sha512-hpr+J05B2FVYUAXHeK1YyI267J/dDDhMU6B6civm8hSY1jYJnBXxzKDKDswzJmtLHryrjhnDjqqp/49t8FALew==",
|
|
||||||
"dev": true,
|
|
||||||
"license": "MIT",
|
|
||||||
"dependencies": {
|
|
||||||
"postcss-value-parser": "^4.0.0",
|
|
||||||
"read-cache": "^1.0.0",
|
|
||||||
"resolve": "^1.1.7"
|
|
||||||
},
|
|
||||||
"engines": {
|
|
||||||
"node": ">=14.0.0"
|
|
||||||
},
|
|
||||||
"peerDependencies": {
|
|
||||||
"postcss": "^8.0.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/postcss-js": {
|
|
||||||
"version": "4.1.0",
|
|
||||||
"resolved": "https://registry.npmmirror.com/postcss-js/-/postcss-js-4.1.0.tgz",
|
|
||||||
"integrity": "sha512-oIAOTqgIo7q2EOwbhb8UalYePMvYoIeRY2YKntdpFQXNosSu3vLrniGgmH9OKs/qAkfoj5oB3le/7mINW1LCfw==",
|
|
||||||
"dev": true,
|
|
||||||
"funding": [
|
|
||||||
{
|
|
||||||
"type": "opencollective",
|
|
||||||
"url": "https://opencollective.com/postcss/"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "github",
|
|
||||||
"url": "https://github.com/sponsors/ai"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"license": "MIT",
|
|
||||||
"dependencies": {
|
|
||||||
"camelcase-css": "^2.0.1"
|
|
||||||
},
|
|
||||||
"engines": {
|
|
||||||
"node": "^12 || ^14 || >= 16"
|
|
||||||
},
|
|
||||||
"peerDependencies": {
|
|
||||||
"postcss": "^8.4.21"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/postcss-lab-function": {
|
"node_modules/postcss-lab-function": {
|
||||||
"version": "7.0.8",
|
"version": "7.0.8",
|
||||||
"resolved": "https://registry.npmjs.org/postcss-lab-function/-/postcss-lab-function-7.0.8.tgz",
|
"resolved": "https://registry.npmjs.org/postcss-lab-function/-/postcss-lab-function-7.0.8.tgz",
|
||||||
@@ -10538,71 +10417,6 @@
|
|||||||
"postcss": "^8.4"
|
"postcss": "^8.4"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/postcss-load-config": {
|
|
||||||
"version": "4.0.2",
|
|
||||||
"resolved": "https://registry.npmmirror.com/postcss-load-config/-/postcss-load-config-4.0.2.tgz",
|
|
||||||
"integrity": "sha512-bSVhyJGL00wMVoPUzAVAnbEoWyqRxkjv64tUl427SKnPrENtq6hJwUojroMz2VB+Q1edmi4IfrAPpami5VVgMQ==",
|
|
||||||
"dev": true,
|
|
||||||
"funding": [
|
|
||||||
{
|
|
||||||
"type": "opencollective",
|
|
||||||
"url": "https://opencollective.com/postcss/"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "github",
|
|
||||||
"url": "https://github.com/sponsors/ai"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"license": "MIT",
|
|
||||||
"dependencies": {
|
|
||||||
"lilconfig": "^3.0.0",
|
|
||||||
"yaml": "^2.3.4"
|
|
||||||
},
|
|
||||||
"engines": {
|
|
||||||
"node": ">= 14"
|
|
||||||
},
|
|
||||||
"peerDependencies": {
|
|
||||||
"postcss": ">=8.0.9",
|
|
||||||
"ts-node": ">=9.0.0"
|
|
||||||
},
|
|
||||||
"peerDependenciesMeta": {
|
|
||||||
"postcss": {
|
|
||||||
"optional": true
|
|
||||||
},
|
|
||||||
"ts-node": {
|
|
||||||
"optional": true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/postcss-load-config/node_modules/lilconfig": {
|
|
||||||
"version": "3.1.3",
|
|
||||||
"resolved": "https://registry.npmmirror.com/lilconfig/-/lilconfig-3.1.3.tgz",
|
|
||||||
"integrity": "sha512-/vlFKAoH5Cgt3Ie+JLhRbwOsCQePABiU3tJ1egGvyQ+33R/vcwM2Zl2QR/LzjsBeItPt3oSVXapn+m4nQDvpzw==",
|
|
||||||
"dev": true,
|
|
||||||
"license": "MIT",
|
|
||||||
"engines": {
|
|
||||||
"node": ">=14"
|
|
||||||
},
|
|
||||||
"funding": {
|
|
||||||
"url": "https://github.com/sponsors/antonk52"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/postcss-load-config/node_modules/yaml": {
|
|
||||||
"version": "2.8.2",
|
|
||||||
"resolved": "https://registry.npmmirror.com/yaml/-/yaml-2.8.2.tgz",
|
|
||||||
"integrity": "sha512-mplynKqc1C2hTVYxd0PU2xQAc22TI1vShAYGksCCfxbn/dFwnHTNi1bvYsBTkhdUNtGIf5xNOg938rrSSYvS9A==",
|
|
||||||
"dev": true,
|
|
||||||
"license": "ISC",
|
|
||||||
"bin": {
|
|
||||||
"yaml": "bin.mjs"
|
|
||||||
},
|
|
||||||
"engines": {
|
|
||||||
"node": ">= 14.6"
|
|
||||||
},
|
|
||||||
"funding": {
|
|
||||||
"url": "https://github.com/sponsors/eemeli"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/postcss-loader": {
|
"node_modules/postcss-loader": {
|
||||||
"version": "6.2.1",
|
"version": "6.2.1",
|
||||||
"resolved": "https://registry.npmjs.org/postcss-loader/-/postcss-loader-6.2.1.tgz",
|
"resolved": "https://registry.npmjs.org/postcss-loader/-/postcss-loader-6.2.1.tgz",
|
||||||
@@ -10860,32 +10674,6 @@
|
|||||||
"postcss": "^8.1.0"
|
"postcss": "^8.1.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/postcss-nested": {
|
|
||||||
"version": "6.2.0",
|
|
||||||
"resolved": "https://registry.npmmirror.com/postcss-nested/-/postcss-nested-6.2.0.tgz",
|
|
||||||
"integrity": "sha512-HQbt28KulC5AJzG+cZtj9kvKB93CFCdLvog1WFLf1D+xmMvPGlBstkpTEZfK5+AN9hfJocyBFCNiqyS48bpgzQ==",
|
|
||||||
"dev": true,
|
|
||||||
"funding": [
|
|
||||||
{
|
|
||||||
"type": "opencollective",
|
|
||||||
"url": "https://opencollective.com/postcss/"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "github",
|
|
||||||
"url": "https://github.com/sponsors/ai"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"license": "MIT",
|
|
||||||
"dependencies": {
|
|
||||||
"postcss-selector-parser": "^6.1.1"
|
|
||||||
},
|
|
||||||
"engines": {
|
|
||||||
"node": ">=12.0"
|
|
||||||
},
|
|
||||||
"peerDependencies": {
|
|
||||||
"postcss": "^8.2.14"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/postcss-nesting": {
|
"node_modules/postcss-nesting": {
|
||||||
"version": "13.0.1",
|
"version": "13.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/postcss-nesting/-/postcss-nesting-13.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/postcss-nesting/-/postcss-nesting-13.0.1.tgz",
|
||||||
@@ -12000,26 +11788,6 @@
|
|||||||
"node": ">= 0.8"
|
"node": ">= 0.8"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/read-cache": {
|
|
||||||
"version": "1.0.0",
|
|
||||||
"resolved": "https://registry.npmmirror.com/read-cache/-/read-cache-1.0.0.tgz",
|
|
||||||
"integrity": "sha512-Owdv/Ft7IjOgm/i0xvNDZ1LrRANRfew4b2prF3OWMQLxLfu3bS8FVhCsrSCMK4lR56Y9ya+AThoTpDCTxCmpRA==",
|
|
||||||
"dev": true,
|
|
||||||
"license": "MIT",
|
|
||||||
"dependencies": {
|
|
||||||
"pify": "^2.3.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/read-cache/node_modules/pify": {
|
|
||||||
"version": "2.3.0",
|
|
||||||
"resolved": "https://registry.npmmirror.com/pify/-/pify-2.3.0.tgz",
|
|
||||||
"integrity": "sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==",
|
|
||||||
"dev": true,
|
|
||||||
"license": "MIT",
|
|
||||||
"engines": {
|
|
||||||
"node": ">=0.10.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/read-pkg": {
|
"node_modules/read-pkg": {
|
||||||
"version": "5.2.0",
|
"version": "5.2.0",
|
||||||
"resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-5.2.0.tgz",
|
"resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-5.2.0.tgz",
|
||||||
@@ -13008,39 +12776,6 @@
|
|||||||
"postcss": "^8.2.15"
|
"postcss": "^8.2.15"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/sucrase": {
|
|
||||||
"version": "3.35.1",
|
|
||||||
"resolved": "https://registry.npmmirror.com/sucrase/-/sucrase-3.35.1.tgz",
|
|
||||||
"integrity": "sha512-DhuTmvZWux4H1UOnWMB3sk0sbaCVOoQZjv8u1rDoTV0HTdGem9hkAZtl4JZy8P2z4Bg0nT+YMeOFyVr4zcG5Tw==",
|
|
||||||
"dev": true,
|
|
||||||
"license": "MIT",
|
|
||||||
"dependencies": {
|
|
||||||
"@jridgewell/gen-mapping": "^0.3.2",
|
|
||||||
"commander": "^4.0.0",
|
|
||||||
"lines-and-columns": "^1.1.6",
|
|
||||||
"mz": "^2.7.0",
|
|
||||||
"pirates": "^4.0.1",
|
|
||||||
"tinyglobby": "^0.2.11",
|
|
||||||
"ts-interface-checker": "^0.1.9"
|
|
||||||
},
|
|
||||||
"bin": {
|
|
||||||
"sucrase": "bin/sucrase",
|
|
||||||
"sucrase-node": "bin/sucrase-node"
|
|
||||||
},
|
|
||||||
"engines": {
|
|
||||||
"node": ">=16 || 14 >=14.17"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/sucrase/node_modules/commander": {
|
|
||||||
"version": "4.1.1",
|
|
||||||
"resolved": "https://registry.npmmirror.com/commander/-/commander-4.1.1.tgz",
|
|
||||||
"integrity": "sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==",
|
|
||||||
"dev": true,
|
|
||||||
"license": "MIT",
|
|
||||||
"engines": {
|
|
||||||
"node": ">= 6"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/superjson": {
|
"node_modules/superjson": {
|
||||||
"version": "2.2.2",
|
"version": "2.2.2",
|
||||||
"resolved": "https://registry.npmjs.org/superjson/-/superjson-2.2.2.tgz",
|
"resolved": "https://registry.npmjs.org/superjson/-/superjson-2.2.2.tgz",
|
||||||
@@ -13117,57 +12852,6 @@
|
|||||||
"node": ">= 10"
|
"node": ">= 10"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/tailwindcss": {
|
|
||||||
"version": "3.4.17",
|
|
||||||
"resolved": "https://registry.npmmirror.com/tailwindcss/-/tailwindcss-3.4.17.tgz",
|
|
||||||
"integrity": "sha512-w33E2aCvSDP0tW9RZuNXadXlkHXqFzSkQew/aIa2i/Sj8fThxwovwlXHSPXTbAHwEIhBFXAedUhP2tueAKP8Og==",
|
|
||||||
"dev": true,
|
|
||||||
"license": "MIT",
|
|
||||||
"dependencies": {
|
|
||||||
"@alloc/quick-lru": "^5.2.0",
|
|
||||||
"arg": "^5.0.2",
|
|
||||||
"chokidar": "^3.6.0",
|
|
||||||
"didyoumean": "^1.2.2",
|
|
||||||
"dlv": "^1.1.3",
|
|
||||||
"fast-glob": "^3.3.2",
|
|
||||||
"glob-parent": "^6.0.2",
|
|
||||||
"is-glob": "^4.0.3",
|
|
||||||
"jiti": "^1.21.6",
|
|
||||||
"lilconfig": "^3.1.3",
|
|
||||||
"micromatch": "^4.0.8",
|
|
||||||
"normalize-path": "^3.0.0",
|
|
||||||
"object-hash": "^3.0.0",
|
|
||||||
"picocolors": "^1.1.1",
|
|
||||||
"postcss": "^8.4.47",
|
|
||||||
"postcss-import": "^15.1.0",
|
|
||||||
"postcss-js": "^4.0.1",
|
|
||||||
"postcss-load-config": "^4.0.2",
|
|
||||||
"postcss-nested": "^6.2.0",
|
|
||||||
"postcss-selector-parser": "^6.1.2",
|
|
||||||
"resolve": "^1.22.8",
|
|
||||||
"sucrase": "^3.35.0"
|
|
||||||
},
|
|
||||||
"bin": {
|
|
||||||
"tailwind": "lib/cli.js",
|
|
||||||
"tailwindcss": "lib/cli.js"
|
|
||||||
},
|
|
||||||
"engines": {
|
|
||||||
"node": ">=14.0.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/tailwindcss/node_modules/lilconfig": {
|
|
||||||
"version": "3.1.3",
|
|
||||||
"resolved": "https://registry.npmmirror.com/lilconfig/-/lilconfig-3.1.3.tgz",
|
|
||||||
"integrity": "sha512-/vlFKAoH5Cgt3Ie+JLhRbwOsCQePABiU3tJ1egGvyQ+33R/vcwM2Zl2QR/LzjsBeItPt3oSVXapn+m4nQDvpzw==",
|
|
||||||
"dev": true,
|
|
||||||
"license": "MIT",
|
|
||||||
"engines": {
|
|
||||||
"node": ">=14"
|
|
||||||
},
|
|
||||||
"funding": {
|
|
||||||
"url": "https://github.com/sponsors/antonk52"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/tapable": {
|
"node_modules/tapable": {
|
||||||
"version": "2.2.1",
|
"version": "2.2.1",
|
||||||
"resolved": "https://registry.npmjs.org/tapable/-/tapable-2.2.1.tgz",
|
"resolved": "https://registry.npmjs.org/tapable/-/tapable-2.2.1.tgz",
|
||||||
@@ -13384,54 +13068,6 @@
|
|||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
"node_modules/tinyglobby": {
|
|
||||||
"version": "0.2.15",
|
|
||||||
"resolved": "https://registry.npmmirror.com/tinyglobby/-/tinyglobby-0.2.15.tgz",
|
|
||||||
"integrity": "sha512-j2Zq4NyQYG5XMST4cbs02Ak8iJUdxRM0XI5QyxXuZOzKOINmWurp3smXu3y5wDcJrptwpSjgXHzIQxR0omXljQ==",
|
|
||||||
"dev": true,
|
|
||||||
"license": "MIT",
|
|
||||||
"dependencies": {
|
|
||||||
"fdir": "^6.5.0",
|
|
||||||
"picomatch": "^4.0.3"
|
|
||||||
},
|
|
||||||
"engines": {
|
|
||||||
"node": ">=12.0.0"
|
|
||||||
},
|
|
||||||
"funding": {
|
|
||||||
"url": "https://github.com/sponsors/SuperchupuDev"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/tinyglobby/node_modules/fdir": {
|
|
||||||
"version": "6.5.0",
|
|
||||||
"resolved": "https://registry.npmmirror.com/fdir/-/fdir-6.5.0.tgz",
|
|
||||||
"integrity": "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==",
|
|
||||||
"dev": true,
|
|
||||||
"license": "MIT",
|
|
||||||
"engines": {
|
|
||||||
"node": ">=12.0.0"
|
|
||||||
},
|
|
||||||
"peerDependencies": {
|
|
||||||
"picomatch": "^3 || ^4"
|
|
||||||
},
|
|
||||||
"peerDependenciesMeta": {
|
|
||||||
"picomatch": {
|
|
||||||
"optional": true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/tinyglobby/node_modules/picomatch": {
|
|
||||||
"version": "4.0.3",
|
|
||||||
"resolved": "https://registry.npmmirror.com/picomatch/-/picomatch-4.0.3.tgz",
|
|
||||||
"integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==",
|
|
||||||
"dev": true,
|
|
||||||
"license": "MIT",
|
|
||||||
"engines": {
|
|
||||||
"node": ">=12"
|
|
||||||
},
|
|
||||||
"funding": {
|
|
||||||
"url": "https://github.com/sponsors/jonschlinkert"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/to-regex-range": {
|
"node_modules/to-regex-range": {
|
||||||
"version": "5.0.1",
|
"version": "5.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz",
|
||||||
@@ -13472,13 +13108,6 @@
|
|||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
"node_modules/ts-interface-checker": {
|
|
||||||
"version": "0.1.13",
|
|
||||||
"resolved": "https://registry.npmmirror.com/ts-interface-checker/-/ts-interface-checker-0.1.13.tgz",
|
|
||||||
"integrity": "sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA==",
|
|
||||||
"dev": true,
|
|
||||||
"license": "Apache-2.0"
|
|
||||||
},
|
|
||||||
"node_modules/tslib": {
|
"node_modules/tslib": {
|
||||||
"version": "2.8.1",
|
"version": "2.8.1",
|
||||||
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz",
|
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz",
|
||||||
@@ -13582,9 +13211,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/update-browserslist-db": {
|
"node_modules/update-browserslist-db": {
|
||||||
"version": "1.2.3",
|
"version": "1.1.3",
|
||||||
"resolved": "https://registry.npmmirror.com/update-browserslist-db/-/update-browserslist-db-1.2.3.tgz",
|
"resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.3.tgz",
|
||||||
"integrity": "sha512-Js0m9cx+qOgDxo0eMiFGEueWztz+d4+M3rGlmKPT+T4IS/jP4ylw3Nwpu6cpTTP8R1MAC1kF4VbdLt3ARf209w==",
|
"integrity": "sha512-UxhIZQ+QInVdunkDAaiazvvT/+fXL5Osr0JZlJulepYu6Jd7qJtDZjlur0emRlT71EN3ScPoE7gvsuIKKNavKw==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"funding": [
|
"funding": [
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -23,15 +23,12 @@
|
|||||||
"@vue/cli-plugin-router": "~5.0.0",
|
"@vue/cli-plugin-router": "~5.0.0",
|
||||||
"@vue/cli-plugin-vuex": "~5.0.0",
|
"@vue/cli-plugin-vuex": "~5.0.0",
|
||||||
"@vue/cli-service": "~5.0.0",
|
"@vue/cli-service": "~5.0.0",
|
||||||
"autoprefixer": "^10.4.24",
|
|
||||||
"less": "^4.2.2",
|
"less": "^4.2.2",
|
||||||
"less-loader": "^12.2.0",
|
"less-loader": "^12.2.0",
|
||||||
"postcss": "^8.5.6",
|
|
||||||
"postcss-preset-env": "^10.1.5",
|
"postcss-preset-env": "^10.1.5",
|
||||||
"postcss-px-to-viewport": "^1.1.1",
|
"postcss-px-to-viewport": "^1.1.1",
|
||||||
"postcss-px-viewport": "^0.0.4",
|
"postcss-px-viewport": "^0.0.4",
|
||||||
"postcss-viewport-units": "^0.1.6",
|
"postcss-viewport-units": "^0.1.6"
|
||||||
"tailwindcss": "^3.4.17"
|
|
||||||
},
|
},
|
||||||
"browserslist": [
|
"browserslist": [
|
||||||
"> 1%",
|
"> 1%",
|
||||||
|
|||||||
13
postcss.config.js
Normal file
13
postcss.config.js
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
module.exports = {
|
||||||
|
plugins: {
|
||||||
|
'postcss-px-to-viewport': {
|
||||||
|
viewportWidth: 1600, // 视窗的宽度,对应设计稿宽度
|
||||||
|
viewportHeight: 900, // 视窗的高度,对应设计稿高度
|
||||||
|
unitPrecision: 3, // 指定 px 转换为视窗单位值的小数位数
|
||||||
|
viewportUnit: 'vw', // 指定需要转换成的视窗单位,vw 或者 vh
|
||||||
|
selectorBlackList: ['.ignore', '.hairlines'], // 指定不需要转换的类
|
||||||
|
minPixelValue: 1, // 小于或等于 1 px 不转换为视窗单位
|
||||||
|
mediaQuery: false // 允许在媒体查询中转换 px
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
@@ -9,68 +9,7 @@
|
|||||||
<title>
|
<title>
|
||||||
<%= webpackConfig.name %>
|
<%= webpackConfig.name %>
|
||||||
</title>
|
</title>
|
||||||
|
<!-- pywebview API 自动注入,无需手动引入脚本 -->
|
||||||
<!-- Fonts -->
|
|
||||||
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700&display=swap"
|
|
||||||
rel="stylesheet" />
|
|
||||||
<link href="https://fonts.googleapis.com/icon?family=Material+Icons+Round" rel="stylesheet" />
|
|
||||||
|
|
||||||
<!-- Tailwind CSS -->
|
|
||||||
<script src="https://cdn.tailwindcss.com?plugins=forms,typography"></script>
|
|
||||||
<script>
|
|
||||||
tailwind.config = {
|
|
||||||
darkMode: "class",
|
|
||||||
theme: {
|
|
||||||
extend: {
|
|
||||||
colors: {
|
|
||||||
primary: "#0066FF", // Cyber Blue
|
|
||||||
secondary: "#6366F1", // Electric Indigo
|
|
||||||
"background-light": "#F8FAFC",
|
|
||||||
"background-dark": "#0F172A",
|
|
||||||
},
|
|
||||||
fontFamily: {
|
|
||||||
display: ["Inter", "sans-serif"],
|
|
||||||
},
|
|
||||||
borderRadius: {
|
|
||||||
DEFAULT: "12px",
|
|
||||||
'xl': '20px',
|
|
||||||
},
|
|
||||||
boxShadow: {
|
|
||||||
'premium': '0 4px 20px -2px rgba(0, 0, 0, 0.05), 0 2px 10px -2px rgba(0, 0, 0, 0.02)',
|
|
||||||
'glass': 'inset 0 0 0 1px rgba(255, 255, 255, 0.4)',
|
|
||||||
}
|
|
||||||
},
|
|
||||||
},
|
|
||||||
};
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<!-- Global Styles -->
|
|
||||||
<style>
|
|
||||||
body {
|
|
||||||
font-family: 'Inter', sans-serif;
|
|
||||||
}
|
|
||||||
|
|
||||||
.glass-card {
|
|
||||||
background: rgba(255, 255, 255, 0.7);
|
|
||||||
backdrop-filter: blur(12px);
|
|
||||||
-webkit-backdrop-filter: blur(12px);
|
|
||||||
border: 1px solid rgba(255, 255, 255, 0.3);
|
|
||||||
}
|
|
||||||
|
|
||||||
.sidebar-active {
|
|
||||||
background: linear-gradient(90deg, #F0F7FF 0%, #FFFFFF 100%);
|
|
||||||
border-right: 3px solid #0066FF;
|
|
||||||
box-shadow: 4px 0 15px -5px rgba(0, 102, 255, 0.15);
|
|
||||||
}
|
|
||||||
|
|
||||||
.subtle-grid {
|
|
||||||
background-image: radial-gradient(#E2E8F0 0.5px, transparent 0.5px);
|
|
||||||
background-size: 24px 24px;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* QT WebChannel */
|
|
||||||
</style>
|
|
||||||
<script src="qrc:///qtwebchannel/qwebchannel.js"></script>
|
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
<body>
|
<body>
|
||||||
@@ -82,11 +21,19 @@
|
|||||||
<!-- built files will be auto injected -->
|
<!-- built files will be auto injected -->
|
||||||
</body>
|
</body>
|
||||||
<style>
|
<style>
|
||||||
|
html,
|
||||||
body {
|
body {
|
||||||
margin: 0;
|
margin: 0;
|
||||||
padding: 0;
|
padding: 0;
|
||||||
/* width: 1600px;
|
overflow: hidden;
|
||||||
height: 900px; */
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
#app {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
overflow: hidden;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
|
|||||||
@@ -76,7 +76,3 @@ export function accountName(str) {
|
|||||||
export function liveHostDetail(data) {
|
export function liveHostDetail(data) {
|
||||||
return postAxios({ url: 'api/save_data/live_host_detail', data })
|
return postAxios({ url: 'api/save_data/live_host_detail', data })
|
||||||
}
|
}
|
||||||
|
|
||||||
export function revenueStats(hostId) {
|
|
||||||
return getAxios({ url: 'api/save_data/revenue_stats?displayId=' + hostId })
|
|
||||||
}
|
|
||||||
|
|||||||
Binary file not shown.
|
Before Width: | Height: | Size: 66 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 363 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 48 KiB |
@@ -1,63 +1,148 @@
|
|||||||
<template>
|
<template>
|
||||||
<aside class="w-64 bg-white dark:bg-slate-900 border-r border-slate-200 dark:border-slate-800 flex flex-col z-20 h-full">
|
<div class="sidebar">
|
||||||
<div class="p-8 flex items-center gap-3">
|
<div class="logo">
|
||||||
<div class="w-10 h-10 bg-primary rounded-xl flex items-center justify-center shadow-lg shadow-primary/20">
|
<!-- <img style="margin-right: 10px;" src="@/assets/logo.png"> -->
|
||||||
<span class="text-white font-bold text-xl">TK
|
<img src="@/assets/logotext.png">
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
<h1 class="text-xl font-bold tracking-tight text-slate-900 dark:text-white">Yolo <span class="text-primary">助手</span>
|
|
||||||
</h1>
|
|
||||||
</div>
|
</div>
|
||||||
|
<ul>
|
||||||
|
<li @click="updateActiveIndex(1)">
|
||||||
|
<div>
|
||||||
|
<img v-show="activeIndex == 1" src="@/assets/navAction.png" autoplay loop muted class="background-img">
|
||||||
|
<div style="display: flex;">
|
||||||
|
<img v-show="activeIndex == 1" src="@/assets/workAction.png" style="margin-right: 10px;">
|
||||||
|
<img v-show="activeIndex == 2" src="@/assets/workAction.png" style="margin-right: 10px;">
|
||||||
|
<div :style="activeIndex == 1 ? 'color: #000' : 'color: #fff'" class="center-justify">{{
|
||||||
|
$t('menu.workbenches')
|
||||||
|
}}</div>
|
||||||
|
|
||||||
<nav class="flex-1 px-4 space-y-4">
|
</div>
|
||||||
<a
|
</div>
|
||||||
class="flex items-center gap-3 px-4 py-4 rounded-lg font-medium cursor-pointer transition-colors"
|
</li>
|
||||||
:class="activeIndex == 1 ? 'sidebar-active text-primary' : 'text-slate-500 hover:bg-slate-50 dark:hover:bg-slate-800'"
|
<li @click="updateActiveIndex(2)">
|
||||||
@click="updateActiveIndex(1)"
|
<div>
|
||||||
>
|
<img v-show="activeIndex == 2" src="@/assets/navAction.png" autoplay loop muted class="background-img">
|
||||||
<span class="material-icons-round">grid_view</span>
|
|
||||||
{{ $t('menu.workbenches') }}
|
<div style="display: flex;">
|
||||||
|
<img v-show="activeIndex == 2" src="@/assets/listAction.png" style="margin-right: 10px;">
|
||||||
|
<img v-show="activeIndex == 1" src="@/assets/listAction.png" style="margin-right: 10px;">
|
||||||
|
<div :style="activeIndex == 2 ? 'color: #000' : 'color: #fff'" class="center-justify">{{
|
||||||
|
$t('menu.hostList')
|
||||||
|
}}</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
<a @click="$router.push('/')" href="javascript:void(0);"
|
||||||
|
style="position: absolute; bottom: 30px; color: aliceblue; font-size: 20px; font-weight: 500;">
|
||||||
|
{{
|
||||||
|
$t('menu.logout')
|
||||||
|
}}
|
||||||
</a>
|
</a>
|
||||||
|
|
||||||
<a
|
|
||||||
class="flex items-center gap-3 px-4 py-4 rounded-lg font-medium cursor-pointer transition-colors"
|
|
||||||
:class="activeIndex == 2 ? 'sidebar-active text-primary' : 'text-slate-500 hover:bg-slate-50 dark:hover:bg-slate-800'"
|
|
||||||
@click="updateActiveIndex(2)"
|
|
||||||
>
|
|
||||||
<span class="material-icons-round">person_search</span>
|
|
||||||
{{ $t('menu.hostList') }}
|
|
||||||
</a>
|
|
||||||
</nav>
|
|
||||||
|
|
||||||
<div class="p-6 border-t border-slate-100 dark:border-slate-800">
|
|
||||||
<button
|
|
||||||
class="flex items-center gap-3 text-slate-500 hover:text-red-500 transition-colors w-full px-4 py-2"
|
|
||||||
@click="$router.push('/')"
|
|
||||||
>
|
|
||||||
<span class="material-icons-round text-lg">logout</span>
|
|
||||||
<span class="font-medium">{{ $t('menu.logout') }}</span>
|
|
||||||
</button>
|
|
||||||
</div>
|
</div>
|
||||||
</aside>
|
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
import { ref } from 'vue';
|
import { ref, reactive, onMounted } from 'vue';
|
||||||
import { getUser } from '@/utils/storage'
|
import { getUser } from '@/utils/storage'
|
||||||
import { defineEmits } from 'vue';
|
import { defineEmits } from 'vue';
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
const userInfo = ref(getUser())
|
const userInfo = ref(getUser())
|
||||||
|
|
||||||
let activeIndex = ref(1);
|
let activeIndex = ref(1);
|
||||||
|
|
||||||
const emit = defineEmits(['activeIndex']);
|
const emit = defineEmits(['activeIndex']);
|
||||||
|
|
||||||
|
|
||||||
const updateActiveIndex = (index) => {
|
const updateActiveIndex = (index) => {
|
||||||
activeIndex.value = index;
|
activeIndex.value = index;
|
||||||
emit('activeIndex', index);
|
emit('activeIndex', index);
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped>
|
<style scoped lang="less">
|
||||||
/* Scoped styles are minimal now as we use Tailwind */
|
.sidebar {
|
||||||
|
position: fixed;
|
||||||
|
left: 0;
|
||||||
|
top: 0;
|
||||||
|
height: 900px;
|
||||||
|
width: 280px;
|
||||||
|
background-color: @bg-color;
|
||||||
|
padding: 20px;
|
||||||
|
box-sizing: border-box;
|
||||||
|
|
||||||
|
.logo {
|
||||||
|
border-bottom: 1px solid #fff;
|
||||||
|
padding-top: 20px;
|
||||||
|
|
||||||
|
img:nth-of-type(1) {
|
||||||
|
height: 66px;
|
||||||
|
}
|
||||||
|
|
||||||
|
img:nth-of-type(2) {
|
||||||
|
height: 29px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.sidebar ul {
|
||||||
|
list-style: none;
|
||||||
|
padding: 0;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
.sidebar li {
|
||||||
|
margin-top: 50px;
|
||||||
|
padding-top: 30px;
|
||||||
|
padding-left: 30px;
|
||||||
|
margin-bottom: 50px;
|
||||||
|
height: 64px;
|
||||||
|
position: relative;
|
||||||
|
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
cursor: pointer;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
.sidebar a {
|
||||||
|
text-decoration: none;
|
||||||
|
color: #000000;
|
||||||
|
display: block;
|
||||||
|
padding: 8px;
|
||||||
|
border-radius: 4px;
|
||||||
|
|
||||||
|
font-family: Source Han Sans SC;
|
||||||
|
font-weight: 400;
|
||||||
|
font-size: 22px;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/* .sidebar a:hover {
|
||||||
|
background-color: #e0e0e0;
|
||||||
|
} */
|
||||||
|
|
||||||
|
|
||||||
|
.background-img {
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
left: 13px;
|
||||||
|
width: 247px;
|
||||||
|
height: 126px;
|
||||||
|
object-fit: cover;
|
||||||
|
z-index: -1;
|
||||||
|
/* 确保视频在内容之下 */
|
||||||
|
}
|
||||||
|
|
||||||
|
.center-justify {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-around;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
@@ -79,19 +79,5 @@ export default {
|
|||||||
invitationType: 'invitationType',
|
invitationType: 'invitationType',
|
||||||
invitationType1: 'Regular',
|
invitationType1: 'Regular',
|
||||||
invitationType2: 'Golden',
|
invitationType2: 'Golden',
|
||||||
liveSessions: 'Live Sessions',
|
|
||||||
viewSessions: 'View Sessions',
|
|
||||||
liveRevenue: 'Live Revenue',
|
|
||||||
viewRevenue: 'View Revenue',
|
|
||||||
revenueHost: 'Host',
|
|
||||||
todayRevenueUsd: 'Today Revenue (USD)',
|
|
||||||
totalRevenueUsd: 'Total Revenue (USD)',
|
|
||||||
liveDays: 'Live Days',
|
|
||||||
historyRevenueUsd: 'History Revenue (USD)',
|
|
||||||
revenueHigh: 'High',
|
|
||||||
revenueLow: 'Low',
|
|
||||||
revenueTime: 'Time',
|
|
||||||
close: 'Close',
|
|
||||||
selectPlaceholder: 'Please select',
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,10 +1,10 @@
|
|||||||
export default {
|
export default {
|
||||||
login: {
|
login: {
|
||||||
title: '账号登录',
|
title: '账号登陆',
|
||||||
version: '版本号',
|
version: '版本号',
|
||||||
login: '登录',
|
login: '登录',
|
||||||
tenantName: '租户名称',
|
tenantName: '租户名称',
|
||||||
account: '账号',
|
account: '账户',
|
||||||
password: '密码',
|
password: '密码',
|
||||||
Language: '语言设置',
|
Language: '语言设置',
|
||||||
network: '网络设置',
|
network: '网络设置',
|
||||||
@@ -27,7 +27,6 @@
|
|||||||
guildPassPlace: '请输入登录密码',
|
guildPassPlace: '请输入登录密码',
|
||||||
queriedNum: '今日已查询次数',
|
queriedNum: '今日已查询次数',
|
||||||
loginBackend: '登录后台',
|
loginBackend: '登录后台',
|
||||||
workbenches: '工作台',
|
|
||||||
},
|
},
|
||||||
workbenchesSetup: {
|
workbenchesSetup: {
|
||||||
workbenches: '工作台',
|
workbenches: '工作台',
|
||||||
@@ -45,9 +44,11 @@
|
|||||||
num: '个',
|
num: '个',
|
||||||
start: '开始获取数据',
|
start: '开始获取数据',
|
||||||
stop: '停止',
|
stop: '停止',
|
||||||
prompt: '达到数量后停止爬取',
|
prompt: '到达数量后停止爬取',
|
||||||
setHostNum: '设置爬取数量',
|
setHostNum: '设置爬取数量',
|
||||||
unlimitedQuantity: '不限爬取数量',
|
unlimitedQuantity: '不限爬取数量',
|
||||||
|
|
||||||
|
|
||||||
},
|
},
|
||||||
hostList: {
|
hostList: {
|
||||||
placeCountry: '选择国家',
|
placeCountry: '选择国家',
|
||||||
@@ -78,20 +79,6 @@
|
|||||||
sure: '确定',
|
sure: '确定',
|
||||||
invitationType: '邀请类型',
|
invitationType: '邀请类型',
|
||||||
invitationType1: '普票',
|
invitationType1: '普票',
|
||||||
invitationType2: '进阶票',
|
invitationType2: '金票',
|
||||||
liveSessions: '直播场次',
|
|
||||||
viewSessions: '查看场次',
|
|
||||||
liveRevenue: '直播收益',
|
|
||||||
viewRevenue: '查看收益',
|
|
||||||
revenueHost: '主播',
|
|
||||||
todayRevenueUsd: '今日收益(美元)',
|
|
||||||
totalRevenueUsd: '总收益(美元)',
|
|
||||||
liveDays: '直播天数',
|
|
||||||
historyRevenueUsd: '历史收益(美元)',
|
|
||||||
revenueHigh: '高',
|
|
||||||
revenueLow: '低',
|
|
||||||
revenueTime: '时间',
|
|
||||||
close: '关闭',
|
|
||||||
selectPlaceholder: '请选择',
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,74 +1,100 @@
|
|||||||
// pythonBridge.js
|
// pythonBridge.js
|
||||||
|
// 适配 pywebview API (替代原有的 QWebChannel)
|
||||||
import { ref, onMounted } from 'vue';
|
import { ref, onMounted } from 'vue';
|
||||||
|
|
||||||
const bridge = ref(null);
|
const bridge = ref(null);
|
||||||
|
const isReady = ref(false);
|
||||||
|
|
||||||
// 统一安全调用,确保 Qt 响应有回调可执行
|
/**
|
||||||
const callBridge = (method, ...args) => {
|
* 等待 pywebview API 准备就绪
|
||||||
if (!bridge.value || typeof bridge.value[method] !== 'function') return;
|
* @returns {Promise<void>}
|
||||||
const last = args[args.length - 1];
|
*/
|
||||||
const hasCallback = typeof last === 'function';
|
const waitForPywebview = () => {
|
||||||
const callback = hasCallback ? args.pop() : () => { };
|
return new Promise((resolve) => {
|
||||||
bridge.value[method](...args, callback);
|
// 如果已经存在,直接返回
|
||||||
};
|
if (window.pywebview && window.pywebview.api) {
|
||||||
|
resolve();
|
||||||
// 防御:若 Qt 返回了未知 id,忽略以免 execCallbacks 报错
|
|
||||||
const patchQWebChannel = () => {
|
|
||||||
if (!window.QWebChannel || QWebChannel.__patchedIgnoreMissing) return;
|
|
||||||
const originalHandleResponse = QWebChannel.prototype.handleResponse;
|
|
||||||
QWebChannel.__patchedIgnoreMissing = true;
|
|
||||||
QWebChannel.prototype.handleResponse = function (message) {
|
|
||||||
const cb = this.execCallbacks && this.execCallbacks[message.id];
|
|
||||||
if (message.id && typeof cb !== 'function') {
|
|
||||||
console.warn('忽略未知的 WebChannel 响应', message);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
return originalHandleResponse.call(this, message);
|
// 监听 pywebviewready 事件
|
||||||
};
|
window.addEventListener('pywebviewready', () => {
|
||||||
|
resolve();
|
||||||
|
}, { once: true });
|
||||||
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
// 初始化 QWebChannel
|
/**
|
||||||
const initBridge = () => {
|
* 统一安全调用 pywebview API
|
||||||
if (/localhost/.test(window.location.href)) return;
|
* pywebview 的方法调用会返回 Promise
|
||||||
patchQWebChannel();
|
*/
|
||||||
new QWebChannel(qt.webChannelTransport, (channel) => {
|
const callBridge = async (method, ...args) => {
|
||||||
// 兜底:任何缺失的回调都返回空函数,避免 execCallbacks 报错
|
if (!bridge.value || typeof bridge.value[method] !== 'function') {
|
||||||
channel.execCallbacks = new Proxy(channel.execCallbacks || {}, {
|
console.warn(`[pythonBridge] 方法不存在: ${method}`);
|
||||||
get(target, prop) {
|
return null;
|
||||||
const val = target[prop];
|
}
|
||||||
if (typeof val === 'function') return val;
|
try {
|
||||||
// 返回空函数,确保 handleResponse 可调用
|
const result = await bridge.value[method](...args);
|
||||||
return () => { };
|
return result;
|
||||||
},
|
} catch (error) {
|
||||||
set(target, prop, value) {
|
console.error(`[pythonBridge] 调用 ${method} 失败:`, error);
|
||||||
target[prop] = value;
|
return null;
|
||||||
return true;
|
}
|
||||||
},
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 初始化 pywebview 桥接
|
||||||
|
*/
|
||||||
|
const initBridge = async () => {
|
||||||
|
// 监听 DevTools 快捷键 (Ctrl + Shift + P)
|
||||||
|
window.addEventListener('keydown', (e) => {
|
||||||
|
// 1. 自定义快捷键: Ctrl + Shift + P -> 调用后端
|
||||||
|
if (e.ctrlKey && e.shiftKey && (e.key === 'p' || e.key === 'P')) {
|
||||||
|
e.preventDefault();
|
||||||
|
callBridge('openDevTools');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2. 屏蔽 F12 (防止用户按下 F12 打开)
|
||||||
|
if (e.key === 'F12') {
|
||||||
|
e.preventDefault();
|
||||||
|
return;
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
bridge.value = channel.objects.bridge;
|
// 开发环境 (localhost) 不初始化
|
||||||
});
|
if (/localhost/.test(window.location.href)) {
|
||||||
|
console.log('[pythonBridge] 开发环境,跳过初始化');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
await waitForPywebview();
|
||||||
|
|
||||||
|
if (window.pywebview && window.pywebview.api) {
|
||||||
|
bridge.value = window.pywebview.api;
|
||||||
|
isReady.value = true;
|
||||||
|
console.log('[pythonBridge] 初始化成功');
|
||||||
|
} else {
|
||||||
|
console.error('[pythonBridge] pywebview API 初始化失败');
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
export function usePythonBridge() {
|
export function usePythonBridge() {
|
||||||
// 调用 Python 方法
|
// 调用 Python 方法
|
||||||
const fetchDataConfig = (data) => {
|
const fetchDataConfig = async (data) => {
|
||||||
return new Promise((resolve) => {
|
if (!bridge.value) return null;
|
||||||
if (!bridge.value) return resolve(null);
|
return await callBridge('fetchDataConfig', data);
|
||||||
callBridge('fetchDataConfig', data, (result) => {
|
|
||||||
resolve(result);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// 查询获取主播的数据
|
// 查询获取主播的数据
|
||||||
const fetchDataCount = () => {
|
const fetchDataCount = async () => {
|
||||||
return new Promise((resolve) => {
|
if (!bridge.value) return null;
|
||||||
if (!bridge.value) return resolve(null);
|
const result = await callBridge('fetchDataCount');
|
||||||
callBridge('fetchDataCount', (result) => {
|
// pywebview 返回的是字符串,需要解析
|
||||||
resolve(result);
|
try {
|
||||||
});
|
return typeof result === 'string' ? JSON.parse(result) : result;
|
||||||
});
|
} catch {
|
||||||
|
return result;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// 打开 tk 后台
|
// 打开 tk 后台
|
||||||
@@ -91,23 +117,25 @@ export function usePythonBridge() {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// 查询登录状态
|
// 查询登录状态
|
||||||
const backStageloginStatus = () => {
|
const backStageloginStatus = async () => {
|
||||||
return new Promise((resolve) => {
|
if (!bridge.value) return null;
|
||||||
if (!bridge.value) return resolve(null);
|
const result = await callBridge('backStageloginStatus');
|
||||||
callBridge('backStageloginStatus', (result) => {
|
try {
|
||||||
resolve(result);
|
return typeof result === 'string' ? JSON.parse(result) : result;
|
||||||
});
|
} catch {
|
||||||
});
|
return result;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// 查询登录状态(副账号)
|
// 查询登录状态(副账号)
|
||||||
const backStageloginStatusCopy = () => {
|
const backStageloginStatusCopy = async () => {
|
||||||
return new Promise((resolve) => {
|
if (!bridge.value) return null;
|
||||||
if (!bridge.value) return resolve(null);
|
const result = await callBridge('backStageloginStatusCopy');
|
||||||
callBridge('backStageloginStatusCopy', (result) => {
|
try {
|
||||||
resolve(result);
|
return typeof result === 'string' ? JSON.parse(result) : result;
|
||||||
});
|
} catch {
|
||||||
});
|
return result;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// 导出表格
|
// 导出表格
|
||||||
@@ -120,29 +148,33 @@ export function usePythonBridge() {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// 获取版本号
|
// 获取版本号
|
||||||
const getVersion = () => {
|
const getVersion = async () => {
|
||||||
return new Promise((resolve) => {
|
if (!bridge.value) return null;
|
||||||
if (!bridge.value) return resolve(null);
|
return await callBridge('currentVersion');
|
||||||
callBridge('currentVersion', (result) => {
|
|
||||||
resolve(result);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// 查询TK登录状态
|
// 存储账号信息
|
||||||
const getTkLoginStatus = () => {
|
const storageAccountInfo = async (key, data) => {
|
||||||
return new Promise((resolve) => {
|
if (!bridge.value) return false;
|
||||||
if (!bridge.value) return resolve(false);
|
return await callBridge('storageAccountInfo', key, JSON.stringify(data));
|
||||||
callBridge('getTkLoginStatus', (result) => {
|
};
|
||||||
resolve(result);
|
|
||||||
});
|
// 读取账号信息
|
||||||
});
|
const readAccountInfo = async (key) => {
|
||||||
|
if (!bridge.value) return null;
|
||||||
|
const result = await callBridge('readAccountInfo', key);
|
||||||
|
try {
|
||||||
|
return typeof result === 'string' ? JSON.parse(result) : result;
|
||||||
|
} catch {
|
||||||
|
return result;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// 在组件挂载时初始化桥接
|
// 在组件挂载时初始化桥接
|
||||||
onMounted(initBridge);
|
onMounted(initBridge);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
isReady,
|
||||||
fetchDataConfig,
|
fetchDataConfig,
|
||||||
fetchDataCount,
|
fetchDataCount,
|
||||||
loginBackStage,
|
loginBackStage,
|
||||||
@@ -153,6 +185,7 @@ export function usePythonBridge() {
|
|||||||
exportToExcel,
|
exportToExcel,
|
||||||
stopScript,
|
stopScript,
|
||||||
getVersion,
|
getVersion,
|
||||||
getTkLoginStatus,
|
storageAccountInfo,
|
||||||
|
readAccountInfo,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,18 +1,33 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="main">
|
<div class="main">
|
||||||
<div class="auth-shell">
|
<div class="container">
|
||||||
<div class="top-actions ">
|
<div class="right">
|
||||||
|
<img src="../assets/logoBg.png" class="background-video" alt="">
|
||||||
|
<!-- 设置 -->
|
||||||
|
<div class="center-align">
|
||||||
|
<div></div>
|
||||||
|
<div class="setup">
|
||||||
<div class="setup-item center-justify">
|
<div class="setup-item center-justify">
|
||||||
|
<div></div>
|
||||||
<el-dropdown>
|
<el-dropdown>
|
||||||
<span class="el-dropdown-link">
|
<span class="el-dropdown-link">
|
||||||
<span class="setup-text">{{ $t('login.network') }}</span>
|
<span style="font-size:20px; color: #fff;">
|
||||||
|
{{ $t('login.network') }}
|
||||||
</span>
|
</span>
|
||||||
|
</span>
|
||||||
|
|
||||||
</el-dropdown>
|
</el-dropdown>
|
||||||
</div>
|
</div>
|
||||||
<div class="setup-item center-justify">
|
<div class="setup-item center-justify">
|
||||||
|
<div></div>
|
||||||
<el-dropdown>
|
<el-dropdown>
|
||||||
<span class="el-dropdown-link">
|
<span class="el-dropdown-link">
|
||||||
<span class="setup-text">{{ $t('login.Language') }}</span>
|
<span style="font-size:20px; color: #fff;">
|
||||||
|
{{ $t('login.Language') }}
|
||||||
|
</span>
|
||||||
|
<!-- <el-icon class="el-icon--right">
|
||||||
|
<arrow-down />
|
||||||
|
</el-icon> -->
|
||||||
</span>
|
</span>
|
||||||
<template #dropdown>
|
<template #dropdown>
|
||||||
<el-dropdown-menu>
|
<el-dropdown-menu>
|
||||||
@@ -25,31 +40,41 @@
|
|||||||
</el-dropdown-menu>
|
</el-dropdown-menu>
|
||||||
</template>
|
</template>
|
||||||
</el-dropdown>
|
</el-dropdown>
|
||||||
|
<!-- <el-radio-group v-model="localeData" size="large">
|
||||||
|
<el-radio-button @click="switchLanguage('zh')" label="中文" />
|
||||||
|
<el-radio-button @click="switchLanguage('en')" label="English" />
|
||||||
|
</el-radio-group> -->
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="auth-card">
|
</div>
|
||||||
<div class="auth-left">
|
<div class="center-line" style="margin-top: 40px;">
|
||||||
|
<!-- logo -->
|
||||||
<div class="logo">
|
<div class="logo">
|
||||||
<img class="logo-image" src="@/assets/logo2.png" alt="">
|
<div class="center-justify" style="height: 80px; width: 300px;">
|
||||||
<span class="logo-title">TK主播数据助手</span>
|
<!-- <img style="margin-right: 20px;height: 100%;" src="@/assets/logo.png"> -->
|
||||||
|
<img style="height: 100%;" src="@/assets/logotext.png">
|
||||||
</div>
|
</div>
|
||||||
<div class="welcome">{{ $t('login.title') }}</div>
|
</div>
|
||||||
|
|
||||||
|
<!-- From -->
|
||||||
<div class="from">
|
<div class="from">
|
||||||
|
<div class="from-title center-justify">
|
||||||
|
<div>{{ $t('login.title') }}</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div class="from-input">
|
<div class="from-input">
|
||||||
<el-form label-position="left" label-width="100px" :model="formData">
|
<el-form label-position="left" label-width="100px" :model="formData">
|
||||||
<div class="field-label">{{ $t('login.tenantName') }}</div>
|
|
||||||
<div class="from-input-item1">
|
<div class="from-input-item1">
|
||||||
<img src="@/assets/username.png" alt="">
|
<img src="@/assets/username.png" alt="">
|
||||||
<el-input style="height: 25px;" v-model="formData.tenantName"
|
<el-input style="height: 25px;" v-model="formData.tenantName"
|
||||||
:placeholder="$t('login.tenantName')" clearable @keyup.enter="onSubmit" />
|
:placeholder="$t('login.tenantName')" clearable @keyup.enter="onSubmit" />
|
||||||
</div>
|
</div>
|
||||||
<div class="field-label">{{ $t('login.account') }}</div>
|
|
||||||
<div class="from-input-item1">
|
<div class="from-input-item1">
|
||||||
<img src="@/assets/username.png" alt="">
|
<img src="@/assets/username.png" alt="">
|
||||||
<el-input style="height: 25px;" v-model="formData.userId"
|
<el-input style="height: 25px;" v-model="formData.userId"
|
||||||
:placeholder="$t('login.account')" clearable @keyup.enter="onSubmit" />
|
:placeholder="$t('login.account')" clearable @keyup.enter="onSubmit" />
|
||||||
</div>
|
</div>
|
||||||
<div class="field-label">{{ $t('login.password') }}</div>
|
|
||||||
<div class="from-input-item1">
|
<div class="from-input-item1">
|
||||||
<img src="@/assets/password.png" alt="">
|
<img src="@/assets/password.png" alt="">
|
||||||
<el-input style="height: 25px; " v-model="formData.password" type="password"
|
<el-input style="height: 25px; " v-model="formData.password" type="password"
|
||||||
@@ -57,19 +82,18 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="from-input-item">
|
<div class="from-input-item">
|
||||||
<el-button class="loginButton" style="height: 3vw;" color="#4f6ef7" type="primary"
|
<el-button class="loginButton" color="#8f7ee7" type="primary" @click="onSubmit">{{
|
||||||
:loading="isSubmitting" :disabled="isSubmitting" @click="onSubmit">{{
|
|
||||||
$t('login.login') }}</el-button>
|
$t('login.login') }}</el-button>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</el-form>
|
</el-form>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="version">{{ $t('login.version') }}:{{ version }}</div>
|
|
||||||
</div>
|
|
||||||
<div class="auth-right">
|
|
||||||
<img src="@/assets/logoBg2.webp" class="illustration" alt="">
|
|
||||||
</div>
|
</div>
|
||||||
|
<div class="version center-justify ">{{ $t('login.version') }}:{{ version }}</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
@@ -79,6 +103,7 @@ import { ref, reactive, onMounted } from 'vue';
|
|||||||
import { useRouter } from 'vue-router';
|
import { useRouter } from 'vue-router';
|
||||||
import { login, getIdByName } from '@/api/account';
|
import { login, getIdByName } from '@/api/account';
|
||||||
import { getToken, setToken, setUser, setUserPass, getUserPass } from '@/utils/storage';
|
import { getToken, setToken, setUser, setUserPass, getUserPass } from '@/utils/storage';
|
||||||
|
import { ElLoading } from 'element-plus';
|
||||||
import { usePythonBridge } from '@/utils/pythonBridge'
|
import { usePythonBridge } from '@/utils/pythonBridge'
|
||||||
import { useI18n } from 'vue-i18n'
|
import { useI18n } from 'vue-i18n'
|
||||||
|
|
||||||
@@ -92,7 +117,7 @@ function switchLanguage(lang) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const { getVersion, stopScript } = usePythonBridge();
|
const { getVersion, stopScript } = usePythonBridge();
|
||||||
let version = ref('5.9.2');
|
let version = ref('5.1.0');
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
|
|
||||||
stopScript();
|
stopScript();
|
||||||
@@ -107,7 +132,6 @@ onMounted(() => {
|
|||||||
|
|
||||||
|
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
const isSubmitting = ref(false);
|
|
||||||
|
|
||||||
const formData = ref({
|
const formData = ref({
|
||||||
tenantName: getUserPass() == null ? '' : getUserPass().tenantName,
|
tenantName: getUserPass() == null ? '' : getUserPass().tenantName,
|
||||||
@@ -118,10 +142,11 @@ const formData = ref({
|
|||||||
|
|
||||||
|
|
||||||
const onSubmit = () => {
|
const onSubmit = () => {
|
||||||
if (isSubmitting.value) {
|
const loading = ElLoading.service({
|
||||||
return;
|
lock: true,
|
||||||
}
|
text: 'Loading',
|
||||||
isSubmitting.value = true;
|
background: 'rgba(0, 0, 0, 0.7)',
|
||||||
|
});
|
||||||
setUserPass(formData.value);
|
setUserPass(formData.value);
|
||||||
getIdByName(formData.value.tenantName).then((tenantId) => {
|
getIdByName(formData.value.tenantName).then((tenantId) => {
|
||||||
console.log(tenantId)
|
console.log(tenantId)
|
||||||
@@ -130,16 +155,14 @@ const onSubmit = () => {
|
|||||||
username: formData.value.userId,
|
username: formData.value.userId,
|
||||||
password: formData.value.password,
|
password: formData.value.password,
|
||||||
}).then((res) => {
|
}).then((res) => {
|
||||||
isSubmitting.value = false;
|
loading.close();
|
||||||
// console.log(res)
|
// console.log(res)
|
||||||
setToken(res.tokenValue);
|
setToken(res.tokenValue);
|
||||||
setUser(res);
|
setUser(res);
|
||||||
router.push('/nav');
|
router.push('/nav');
|
||||||
}).catch((err) => {
|
}).catch((err) => {
|
||||||
isSubmitting.value = false;
|
loading.close();
|
||||||
});
|
});
|
||||||
}).catch(() => {
|
|
||||||
isSubmitting.value = false;
|
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
||||||
@@ -148,27 +171,157 @@ const onSubmit = () => {
|
|||||||
|
|
||||||
<style lang="less">
|
<style lang="less">
|
||||||
.main {
|
.main {
|
||||||
width: 1600px;
|
width: 100%;
|
||||||
height: 900px;
|
height: 100vh;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
background: linear-gradient(180deg, #f3f5f9 0%, #eef1f5 100%);
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: center;
|
|
||||||
font-family: "Source Han Sans SC", "PingFang SC", "Microsoft YaHei", sans-serif;
|
|
||||||
|
|
||||||
|
/* 页面无法选中 */
|
||||||
-webkit-user-select: none;
|
-webkit-user-select: none;
|
||||||
-moz-user-select: none;
|
-moz-user-select: none;
|
||||||
-ms-user-select: none;
|
-ms-user-select: none;
|
||||||
user-select: none;
|
user-select: none;
|
||||||
|
|
||||||
|
.container {
|
||||||
|
display: flex;
|
||||||
|
box-sizing: border-box;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
|
||||||
|
.right {
|
||||||
|
box-sizing: border-box;
|
||||||
|
position: relative;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
padding: 20px 40px 20px 50px;
|
||||||
|
border-left: 3px solid #23516e;
|
||||||
|
position: relative;
|
||||||
|
/* 添加 position: relative */
|
||||||
|
overflow: hidden;
|
||||||
|
/* 防止内容溢出 */
|
||||||
|
|
||||||
|
.version {
|
||||||
|
color: #fff;
|
||||||
|
position: absolute;
|
||||||
|
font-size: 20px;
|
||||||
|
bottom: 20px;
|
||||||
|
left: calc(50% - 50px);
|
||||||
|
// box-sizing: border-box;
|
||||||
|
// width: 1600px;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
.background-video {
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
z-index: -1;
|
||||||
|
/* 确保视频在内容之下 */
|
||||||
|
}
|
||||||
|
|
||||||
|
.setup {
|
||||||
|
display: flex;
|
||||||
|
color: #fff;
|
||||||
|
|
||||||
|
.setup-item {
|
||||||
|
padding: 10px 6px;
|
||||||
|
display: flex;
|
||||||
|
|
||||||
|
&>div:nth-child(1) {
|
||||||
|
width: 20px;
|
||||||
|
height: 20px;
|
||||||
|
border-radius: 50%;
|
||||||
|
background-color: rgb(255, 255, 255);
|
||||||
|
margin-right: 5px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.logo {
|
||||||
|
padding: 20px 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.from {
|
||||||
|
width: 420px;
|
||||||
|
// height: 320px;
|
||||||
|
color: @bg-color;
|
||||||
|
background-color: #ffffff44;
|
||||||
|
border-radius: 20px;
|
||||||
|
border: 1px solid #fff;
|
||||||
|
padding: 32px;
|
||||||
|
box-sizing: border-box;
|
||||||
|
|
||||||
|
.from-title {
|
||||||
|
font-family: Source Han Sans SC;
|
||||||
|
font-weight: 500;
|
||||||
|
font-size: 24px;
|
||||||
|
color: @bg-color;
|
||||||
|
line-height: 37px;
|
||||||
|
|
||||||
|
|
||||||
|
div {
|
||||||
|
font-size: 20px;
|
||||||
|
font-weight: 600;
|
||||||
|
// border-bottom: 4px solid #1db97d;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.from-input {
|
||||||
|
width: 100%;
|
||||||
|
padding: 15px 0;
|
||||||
|
|
||||||
|
.from-input-item {
|
||||||
|
display: flex;
|
||||||
|
padding: 8px 0;
|
||||||
|
|
||||||
|
.from-input-item-title {
|
||||||
|
color: @bg-color;
|
||||||
|
font-size: 18px;
|
||||||
|
font-weight: 500;
|
||||||
|
width: 80px;
|
||||||
|
height: 50px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.loginButton {
|
||||||
|
width: 359px;
|
||||||
|
height: 50px;
|
||||||
|
background: #FFFFFF;
|
||||||
|
border-radius: 24px;
|
||||||
|
border: 1px solid #FFFFFF;
|
||||||
|
|
||||||
|
|
||||||
|
font-family: Source Han Sans SC;
|
||||||
|
font-weight: 500;
|
||||||
|
font-size: 18px;
|
||||||
|
color: @bg-color;
|
||||||
|
line-height: 37px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.from-input-item1 {
|
||||||
|
display: flex;
|
||||||
|
width: 359px;
|
||||||
|
height: 50px;
|
||||||
|
background: @bg-color-light-light;
|
||||||
|
border-radius: 24px;
|
||||||
|
border: 1px solid #FFFFFF;
|
||||||
|
padding: 12px 25px 13px 25px;
|
||||||
|
box-sizing: border-box;
|
||||||
|
margin-bottom: 16px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.center-line {
|
.center-line {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
// justify-content: center;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.center-justify {
|
.center-justify {
|
||||||
@@ -177,246 +330,37 @@ const onSubmit = () => {
|
|||||||
align-items: center;
|
align-items: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
.auth-shell {
|
.center-align {
|
||||||
width: 1320px;
|
display: flex;
|
||||||
height: 760px;
|
justify-content: space-between;
|
||||||
position: relative;
|
}
|
||||||
|
|
||||||
|
.center-flex {
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
}
|
|
||||||
|
|
||||||
.auth-shell::before,
|
|
||||||
.auth-shell::after {
|
|
||||||
content: "";
|
|
||||||
position: absolute;
|
|
||||||
border-radius: 50%;
|
|
||||||
filter: blur(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
.auth-shell::before {
|
|
||||||
width: 420px;
|
|
||||||
height: 420px;
|
|
||||||
background: radial-gradient(circle, rgba(214, 226, 255, 0.7), rgba(214, 226, 255, 0));
|
|
||||||
left: -80px;
|
|
||||||
top: -40px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.auth-shell::after {
|
|
||||||
width: 360px;
|
|
||||||
height: 360px;
|
|
||||||
background: radial-gradient(circle, rgba(255, 236, 214, 0.6), rgba(255, 236, 214, 0));
|
|
||||||
right: -40px;
|
|
||||||
bottom: -60px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.top-actions {
|
|
||||||
position: absolute;
|
|
||||||
top: 50px;
|
|
||||||
right: 80px;
|
|
||||||
display: flex;
|
|
||||||
gap: 16px;
|
|
||||||
z-index: 2;
|
|
||||||
}
|
|
||||||
|
|
||||||
.setup-item {
|
|
||||||
background: rgba(255, 255, 255, 0.95);
|
|
||||||
border: 1px solid #e1e6f2;
|
|
||||||
border-radius: 16px;
|
|
||||||
padding: 8px 12px 8px 14px;
|
|
||||||
box-shadow: 0 8px 18px rgba(40, 57, 108, 0.12);
|
|
||||||
cursor: pointer;
|
|
||||||
transition: transform 0.2s ease, box-shadow 0.2s ease, border-color 0.2s ease;
|
|
||||||
display: inline-flex;
|
|
||||||
align-items: center;
|
align-items: center;
|
||||||
gap: 6px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.setup-text {
|
|
||||||
font-size: 13px;
|
|
||||||
font-weight: 600;
|
|
||||||
color: #2b3347;
|
|
||||||
letter-spacing: 0.2px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.setup-item::after {
|
|
||||||
content: "";
|
|
||||||
width: 6px;
|
|
||||||
height: 6px;
|
|
||||||
border-right: 2px solid #9aa1b3;
|
|
||||||
border-bottom: 2px solid #9aa1b3;
|
|
||||||
transform: rotate(45deg);
|
|
||||||
margin-top: -2px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.setup-item:hover {
|
|
||||||
transform: translateY(-1px);
|
|
||||||
border-color: #c9d2f4;
|
|
||||||
box-shadow: 0 12px 24px rgba(40, 57, 108, 0.16);
|
|
||||||
}
|
|
||||||
|
|
||||||
.setup-item:active {
|
|
||||||
transform: translateY(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
.auth-card {
|
|
||||||
width: 1200px;
|
|
||||||
height: 680px;
|
|
||||||
display: flex;
|
|
||||||
background: #ffffff;
|
|
||||||
border-radius: 28px;
|
|
||||||
overflow: hidden;
|
|
||||||
box-shadow: 0 24px 60px rgba(40, 57, 108, 0.16);
|
|
||||||
position: relative;
|
|
||||||
z-index: 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
.auth-left {
|
|
||||||
width: 42%;
|
|
||||||
padding: 48px 56px;
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
justify-content: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
.logo {
|
|
||||||
// margin-bottom: 24px;
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
.logo-image {
|
|
||||||
height: 200px;
|
|
||||||
margin-bottom: -20px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.logo-title {
|
|
||||||
font-size: 20px;
|
|
||||||
font-weight: 600;
|
|
||||||
color: #2b3347;
|
|
||||||
letter-spacing: 2px;
|
|
||||||
position: relative;
|
|
||||||
margin-top: 30px;
|
|
||||||
padding: 10px 0px 10px 14px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.logo-title::before {
|
|
||||||
content: "";
|
|
||||||
position: absolute;
|
|
||||||
left: 0;
|
|
||||||
top: 4px;
|
|
||||||
bottom: 4px;
|
|
||||||
width: 4px;
|
|
||||||
border-radius: 2px;
|
|
||||||
background: linear-gradient(180deg, #4f6ef7, #5b7bff);
|
|
||||||
}
|
|
||||||
|
|
||||||
.welcome {
|
|
||||||
font-size: 24px;
|
|
||||||
font-weight: 600;
|
|
||||||
color: #2b3347;
|
|
||||||
margin-bottom: 8px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.from {
|
|
||||||
width: 100%;
|
|
||||||
color: #2b3347;
|
|
||||||
background-color: transparent;
|
|
||||||
border-radius: 0;
|
|
||||||
border: none;
|
|
||||||
padding: 0;
|
|
||||||
box-sizing: border-box;
|
|
||||||
}
|
|
||||||
|
|
||||||
.from-input {
|
|
||||||
width: 100%;
|
|
||||||
padding: 8px 0 0 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.field-label {
|
|
||||||
font-size: 13px;
|
|
||||||
color: #6b7280;
|
|
||||||
margin: 12px 0 6px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.from-input-item {
|
|
||||||
display: flex;
|
|
||||||
padding: 16px 0 0 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.loginButton {
|
|
||||||
width: 100%;
|
|
||||||
height: 48px;
|
|
||||||
background: linear-gradient(135deg, #4f6ef7, #5b7bff);
|
|
||||||
border-radius: 14px;
|
|
||||||
border: none;
|
|
||||||
font-size: 16px;
|
|
||||||
font-weight: 600;
|
|
||||||
color: #ffffff;
|
|
||||||
box-shadow: 0 12px 24px rgba(79, 110, 247, 0.28);
|
|
||||||
}
|
|
||||||
|
|
||||||
.from-input-item1 {
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
width: 100%;
|
|
||||||
height: 48px;
|
|
||||||
background: #f6f8fc;
|
|
||||||
border-radius: 12px;
|
|
||||||
border: 1px solid #e6eaf2;
|
|
||||||
padding: 10px 14px;
|
|
||||||
box-sizing: border-box;
|
|
||||||
margin-bottom: 4px;
|
|
||||||
gap: 10px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.from-input-item1 img {
|
|
||||||
width: 18px;
|
|
||||||
height: 18px;
|
|
||||||
opacity: 0.6;
|
|
||||||
}
|
|
||||||
|
|
||||||
.version {
|
|
||||||
margin-top: 24px;
|
|
||||||
font-size: 12px;
|
|
||||||
color: #9aa1b3;
|
|
||||||
}
|
|
||||||
|
|
||||||
.auth-right {
|
|
||||||
width: 58%;
|
|
||||||
background: linear-gradient(160deg, #f8f9fc 0%, #f0f3f9 100%);
|
|
||||||
position: relative;
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: center;
|
|
||||||
overflow: hidden;
|
|
||||||
}
|
|
||||||
|
|
||||||
.illustration {
|
|
||||||
width: 90%;
|
|
||||||
height: auto;
|
|
||||||
max-height: 88%;
|
|
||||||
object-fit: contain;
|
|
||||||
filter: drop-shadow(0 30px 60px rgba(40, 57, 108, 0.25));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.el-input__wrapper {
|
.el-input__wrapper {
|
||||||
--el-input-focus-border-color: rgba(255, 255, 0, 0);
|
--el-input-focus-border-color: rgba(255, 255, 0, 0);
|
||||||
--el-menu-hover-bg-color: rgba(255, 255, 0, 0);
|
--el-menu-hover-bg-color: rgba(255, 255, 0, 0);
|
||||||
|
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
<style scoped lang="less">
|
<style scoped lang="less">
|
||||||
::v-deep(.el-input__wrapper) {
|
::v-deep(.el-input__wrapper) {
|
||||||
background-color: transparent;
|
background-color: rgba(255, 0, 0, 0);
|
||||||
box-shadow: none;
|
box-shadow: none;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
::v-deep(.el-input__inner) {
|
::v-deep(.el-input__inner) {
|
||||||
color: #2b3347;
|
color: #fff;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
::v-deep(.el-input__inner::placeholder) {
|
::v-deep(.el-input__inner::placeholder) {
|
||||||
color: #9aa1b3;
|
color: @bg-color;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -1,286 +1,176 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="grid grid-cols-1 lg:grid-cols-12 gap-4 mb-4">
|
<div class="center-line workbenches">
|
||||||
<!-- Stat Cards -->
|
<div class="center-align" style="width: 100%; margin: 0 20px;">
|
||||||
<!-- 总数量 (较小) -->
|
<div class="box-card-num1 center-line">
|
||||||
<div
|
<div>{{ $t('workbenches.totalnumber') }}: <span>{{ hostData.totalCount }}</span></div>
|
||||||
class="lg:col-span-2 bg-white dark:bg-slate-900 p-4 rounded-xl shadow-sm border border-slate-100 dark:border-slate-800">
|
<div>{{ $t('workbenches.createHost') }}: <span>{{ hostData.validAnchorsCount }}</span></div>
|
||||||
<div class="flex items-center justify-between mb-1">
|
<div> {{ $t('workbenches.query') }}: <span>{{ hostData.checkedDataCount }}</span></div>
|
||||||
<span class="text-xs font-medium text-slate-500">{{ $t('workbenches.totalnumber') }}</span>
|
<div>{{ $t('workbenches.invite') }}: <span>{{ hostData.canInvitationCount }}</span></div>
|
||||||
<span class="material-icons-round text-primary/40 text-lg">analytics</span>
|
<div>{{ $t('workbenches.runTime') }}: <span>{{ formattedTime }}</span></div>
|
||||||
</div>
|
</div>
|
||||||
<div class="text-xl font-bold text-slate-900 dark:text-white">{{ hostData.totalCount }}</div>
|
<div class="center-line" style="padding-top: 15vh;">
|
||||||
|
<el-button class="open-login" type="primary" @click="openTK">{{ $t('workbenches.openTK') }}</el-button>
|
||||||
|
<!-- <el-button class="open-login" type="primary" @click="startTimer">计时开始</el-button> -->
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- 新建主播 (较小) -->
|
|
||||||
<div
|
|
||||||
class="lg:col-span-2 bg-white dark:bg-slate-900 p-4 rounded-xl shadow-sm border border-slate-100 dark:border-slate-800">
|
|
||||||
<div class="flex items-center justify-between mb-1">
|
|
||||||
<span class="text-xs font-medium text-slate-500">{{ $t('workbenches.createHost') }}</span>
|
|
||||||
<span class="material-icons-round text-secondary/40 text-lg">person_add</span>
|
|
||||||
</div>
|
|
||||||
<div class="text-xl font-bold text-slate-900 dark:text-white">{{ hostData.validAnchorsCount }}</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- 查询 (较小) -->
|
|
||||||
<div
|
|
||||||
class="lg:col-span-2 bg-white dark:bg-slate-900 p-4 rounded-xl shadow-sm border border-slate-100 dark:border-slate-800">
|
|
||||||
<div class="flex items-center justify-between mb-1">
|
|
||||||
<span class="text-xs font-medium text-slate-500">{{ $t('workbenches.query') }}</span>
|
|
||||||
<span class="material-icons-round text-amber-400/60 text-lg">search</span>
|
|
||||||
</div>
|
|
||||||
<div class="text-xl font-bold text-slate-900 dark:text-white">{{ hostData.checkedDataCount }}</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- 邀请 (较大,突出显示) -->
|
|
||||||
<div
|
|
||||||
class="lg:col-span-3 bg-gradient-to-br from-primary to-blue-600 p-5 rounded-xl shadow-lg shadow-primary/20 text-white relative overflow-hidden">
|
|
||||||
<div class="absolute top-0 right-0 w-24 h-24 bg-white/10 rounded-full -translate-y-1/2 translate-x-1/2"></div>
|
|
||||||
<div class="flex items-center justify-between mb-2 relative z-10">
|
|
||||||
<span class="text-sm font-medium text-white/80">{{ $t('workbenches.invite') }}</span>
|
|
||||||
<span class="material-icons-round text-white/60">mail_outline</span>
|
|
||||||
</div>
|
|
||||||
<div class="text-3xl font-bold text-white relative z-10">{{ hostData.canInvitationCount }}</div>
|
|
||||||
<div class="text-xs text-white/60 mt-1">可邀请主播</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- 运行时间 (较大) -->
|
|
||||||
<div
|
|
||||||
class="lg:col-span-3 bg-white dark:bg-slate-900 p-5 rounded-xl shadow-sm border border-slate-100 dark:border-slate-800 flex flex-col justify-center">
|
|
||||||
<div class="flex items-center justify-between">
|
|
||||||
<div>
|
<div>
|
||||||
<span class="text-xs font-semibold text-slate-400 uppercase tracking-wider block mb-1">{{
|
|
||||||
$t('workbenches.runTime') }}</span>
|
<el-card class="box-card-num" v-for="(item, index) in 2" :key="index">
|
||||||
<div class="text-2xl font-mono font-bold text-primary">{{ formattedTime }}</div>
|
<div class="center-justify">
|
||||||
|
<div class="from-input-item">
|
||||||
|
<div class="from-input-item-title center-justify">
|
||||||
|
{{ $t('workbenches.guildAccount') }}:
|
||||||
</div>
|
</div>
|
||||||
<div class="flex items-center gap-2">
|
<el-input :disabled="!(tkData[index].code == 0 && !isLogin[index])"
|
||||||
<span class="w-4 h-4 rounded-full" :class="isTkLoggedIn ? 'bg-emerald-500' : 'bg-red-500'"></span>
|
v-model="tkData[index].account" :placeholder="$t('workbenches.guildAccountPlace')"
|
||||||
<button @click="openTK"
|
clearable />
|
||||||
class="bg-primary hover:bg-blue-700 text-white px-4 py-2 rounded-lg text-sm font-semibold shadow-lg shadow-primary/25">
|
|
||||||
{{ $t('workbenches.openTK') }}
|
|
||||||
</button>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div class="from-input-item">
|
||||||
|
<div class="from-input-item-title center-justify">
|
||||||
|
{{ $t('workbenches.guildPass') }}:
|
||||||
</div>
|
</div>
|
||||||
|
<el-input :disabled="!(tkData[index].code == 0 && !isLogin[index])"
|
||||||
|
v-model="tkData[index].password" type="password"
|
||||||
|
:placeholder="$t('workbenches.guildPassPlace')" show-password />
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<el-button class="open-login" style="margin-left: 60px;"
|
||||||
|
:disabled="!(tkData[index].code == 0 && !isLogin[index])" type="primary"
|
||||||
|
@click="loginTK(index)">{{ $t('workbenches.loginBackend') }}</el-button>
|
||||||
|
<div v-if="tkData[index].code == 0" class="loginState"></div>
|
||||||
|
<div v-if="tkData[index].code == 1" class="loginState" style="background-color: green;"></div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
<div class="todayCount"> {{ $t('workbenches.queriedNum') }}:{{ tkData[index].num }}</div>
|
||||||
|
</el-card>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Guild Accounts -->
|
<div class="container ">
|
||||||
<div class="grid grid-cols-1 md:grid-cols-2 gap-4 mb-4">
|
|
||||||
<div v-for="(item, index) in 2" :key="index" class="bg-white border border-slate-100 p-5 rounded-xl shadow-sm">
|
|
||||||
<div class="flex justify-between items-center mb-6">
|
|
||||||
<div class="flex items-center gap-2">
|
|
||||||
<span class="w-4 h-4 rounded-full" :class="tkData[index].code == 1 ? 'bg-emerald-500' : 'bg-red-500'"></span>
|
|
||||||
<h3 class="font-bold text-slate-800 dark:text-white">{{ $t('workbenches.guildAccount') }} {{ index === 0 ? 'A'
|
|
||||||
: 'B' }}</h3>
|
|
||||||
</div>
|
|
||||||
<span class=" text-slate-500" style="font-size: 17px;">{{ $t('workbenches.queriedNum') }}: {{
|
|
||||||
tkData[index].num }}</span>
|
|
||||||
</div>
|
|
||||||
<div class="space-y-4">
|
|
||||||
<div class="grid grid-cols-2 gap-4">
|
|
||||||
<div>
|
|
||||||
<label class="text-xs font-semibold text-slate-500 mb-1 block">{{ $t('workbenches.guildAccount') }}</label>
|
|
||||||
<el-input v-model="tkData[index].account" :placeholder="$t('workbenches.guildAccountPlace')"
|
|
||||||
:disabled="!(tkData[index].code == 0 && !isLogin[index])" class="el-input-custom" />
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
<label class="text-xs font-semibold text-slate-500 mb-1 block">{{ $t('workbenches.guildPass') }}</label>
|
|
||||||
<el-input v-model="tkData[index].password" type="password" show-password
|
|
||||||
:placeholder="$t('workbenches.guildPassPlace')" :disabled="!(tkData[index].code == 0 && !isLogin[index])"
|
|
||||||
class="el-input-custom" />
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<button @click="loginTK(index)" :disabled="!(tkData[index].code == 0 && !isLogin[index])"
|
|
||||||
class="w-full bg-slate-900 dark:bg-slate-700 hover:bg-black text-white py-2.5 rounded-lg font-medium transition-all disabled:opacity-50 disabled:cursor-not-allowed">
|
|
||||||
{{ $t('workbenches.loginBackend') }}
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- Configuration Panel -->
|
<el-card class="box-card">
|
||||||
<div
|
<template #header>
|
||||||
class="bg-white dark:bg-slate-900 rounded-2xl shadow-sm border border-slate-100 dark:border-slate-800 overflow-hidden">
|
<div class="card-header">
|
||||||
<div class="p-6 border-b border-slate-100 dark:border-slate-800 flex justify-between items-center">
|
<span class="center-justify"><img src="@/assets/worklogo.png">
|
||||||
<div class="flex items-center gap-3">
|
{{ $t('workbenchesSetup.workbenches') }} </span>
|
||||||
<div class="w-8 h-8 bg-slate-100 dark:bg-slate-800 rounded-lg flex items-center justify-center">
|
<div class="card-header-right">
|
||||||
<span class="material-icons-round text-slate-600 dark:text-slate-400 text-lg">settings</span>
|
|
||||||
</div>
|
|
||||||
<h2 class="font-bold text-slate-800 dark:text-white">{{ $t('workbenchesSetup.workbenches') }}</h2>
|
|
||||||
</div>
|
|
||||||
<div class="flex items-center gap-4 text-sm">
|
|
||||||
<div class="text-slate-500">{{ $t('workbenchesSetup.network') }}: <span class="text-primary font-bold">{{ locale
|
|
||||||
== 'zh' ? countryData : countryDataEN }}</span></div>
|
|
||||||
<div class="flex items-center gap-2">
|
|
||||||
<span class="text-slate-500">指定国家:</span>
|
|
||||||
<select v-model="country_info"
|
|
||||||
class="bg-slate-50 dark:bg-slate-800 border-none rounded-lg text-xs font-medium focus:ring-0">
|
|
||||||
<option value="全部">全部</option>
|
|
||||||
<option v-for="(item, index) in country_Lst" :key="index" :value="item">{{ item }}</option>
|
|
||||||
</select>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="p-6">
|
|
||||||
<div class="grid grid-cols-1 lg:grid-cols-4 gap-6 mb-6">
|
|
||||||
<!-- Coins -->
|
|
||||||
<div>
|
|
||||||
<h4 class="text-sm font-bold text-slate-800 dark:text-white mb-4 flex items-center gap-2">
|
|
||||||
<span class="w-1 h-4 bg-primary rounded-full"></span>
|
|
||||||
{{ $t('workbenchesSetup.setCoinsNum') }}
|
|
||||||
</h4>
|
|
||||||
<div class="space-y-3">
|
|
||||||
<div class="flex shadow-sm rounded-lg overflow-hidden border border-slate-200 dark:border-slate-700">
|
|
||||||
<span
|
|
||||||
class="bg-slate-50 dark:bg-slate-800 px-3 py-2 text-xs font-medium text-slate-500 w-28 flex items-center border-r border-slate-200 dark:border-slate-700">{{
|
|
||||||
$t('workbenchesSetup.minCoinsNum') }}</span>
|
|
||||||
<input
|
|
||||||
class="flex-1 px-4 py-2 text-sm bg-white dark:bg-slate-900 border-none outline-none focus:ring-0 disabled:bg-slate-100"
|
|
||||||
type="number" v-model="pyData.gold.min" :disabled="!pyData.isStart" />
|
|
||||||
</div>
|
|
||||||
<div class="flex shadow-sm rounded-lg overflow-hidden border border-slate-200 dark:border-slate-700">
|
|
||||||
<span
|
|
||||||
class="bg-slate-50 dark:bg-slate-800 px-3 py-2 text-xs font-medium text-slate-500 w-28 flex items-center border-r border-slate-200 dark:border-slate-700">{{
|
|
||||||
$t('workbenchesSetup.maxCoinsNum') }}</span>
|
|
||||||
<input
|
|
||||||
class="flex-1 px-4 py-2 text-sm bg-white dark:bg-slate-900 border-none outline-none focus:ring-0 disabled:bg-slate-100"
|
|
||||||
type="number" v-model="pyData.gold.max" :disabled="!pyData.isStart" />
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- Fans -->
|
<span>
|
||||||
<div>
|
{{ $t('workbenchesSetup.network') }}:{{ locale == 'zh' ? countryData : countryDataEN }}
|
||||||
<h4 class="text-sm font-bold text-slate-800 dark:text-white mb-4 flex items-center gap-2">
|
|
||||||
<span class="w-1 h-4 bg-secondary rounded-full"></span>
|
|
||||||
{{ $t('workbenchesSetup.setFansNum') }}
|
|
||||||
</h4>
|
|
||||||
<div class="space-y-3">
|
|
||||||
<div class="flex shadow-sm rounded-lg overflow-hidden border border-slate-200 dark:border-slate-700">
|
|
||||||
<span
|
|
||||||
class="bg-slate-50 dark:bg-slate-800 px-3 py-2 text-xs font-medium text-slate-500 w-28 flex items-center border-r border-slate-200 dark:border-slate-700">{{
|
|
||||||
$t('workbenchesSetup.minFansNum') }}</span>
|
|
||||||
<input
|
|
||||||
class="flex-1 px-4 py-2 text-sm bg-white dark:bg-slate-900 border-none outline-none focus:ring-0 disabled:bg-slate-100"
|
|
||||||
type="number" v-model="pyData.fans.min" :disabled="!pyData.isStart" />
|
|
||||||
</div>
|
|
||||||
<div class="flex shadow-sm rounded-lg overflow-hidden border border-slate-200 dark:border-slate-700">
|
|
||||||
<span
|
|
||||||
class="bg-slate-50 dark:bg-slate-800 px-3 py-2 text-xs font-medium text-slate-500 w-28 flex items-center border-r border-slate-200 dark:border-slate-700">{{
|
|
||||||
$t('workbenchesSetup.maxFansNum') }}</span>
|
|
||||||
<input
|
|
||||||
class="flex-1 px-4 py-2 text-sm bg-white dark:bg-slate-900 border-none outline-none focus:ring-0 disabled:bg-slate-100"
|
|
||||||
type="number" v-model="pyData.fans.max" :disabled="!pyData.isStart" />
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- Frequency -->
|
|
||||||
<div>
|
|
||||||
<h4 class="text-sm font-bold text-slate-800 dark:text-white mb-4 flex items-center gap-2">
|
|
||||||
<span class="w-1 h-4 bg-emerald-500 rounded-full"></span>
|
|
||||||
{{ $t('workbenchesSetup.setQuery') }}
|
|
||||||
</h4>
|
|
||||||
<div class="space-y-3">
|
|
||||||
<div class="flex shadow-sm rounded-lg overflow-hidden border border-slate-200 dark:border-slate-700">
|
|
||||||
<input
|
|
||||||
class="flex-1 px-4 py-2 text-sm bg-white dark:bg-slate-900 border-none outline-none focus:ring-0 disabled:bg-slate-100"
|
|
||||||
type="number" v-model="pyData.frequency.hour" :disabled="!pyData.isStart" />
|
|
||||||
<span
|
|
||||||
class="bg-slate-100 dark:bg-slate-800 px-3 py-2 text-xs font-medium text-slate-500 w-24 flex items-center justify-center border-l border-slate-200 dark:border-slate-700">{{
|
|
||||||
$t('workbenchesSetup.hour') }}</span>
|
|
||||||
</div>
|
|
||||||
<div class="flex shadow-sm rounded-lg overflow-hidden border border-slate-200 dark:border-slate-700">
|
|
||||||
<input
|
|
||||||
class="flex-1 px-4 py-2 text-sm bg-white dark:bg-slate-900 border-none outline-none focus:ring-0 disabled:bg-slate-100"
|
|
||||||
type="number" v-model="pyData.frequency.day" :disabled="!pyData.isStart" />
|
|
||||||
<span
|
|
||||||
class="bg-slate-100 dark:bg-slate-800 px-3 py-2 text-xs font-medium text-slate-500 w-24 flex items-center justify-center border-l border-slate-200 dark:border-slate-700">{{
|
|
||||||
$t('workbenchesSetup.hour24') }}</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- Quantity Limit -->
|
|
||||||
<div>
|
|
||||||
<h4 class="text-sm font-bold text-slate-800 dark:text-white mb-4 flex items-center gap-2">
|
|
||||||
<span class="w-1 h-4 bg-orange-400 rounded-full"></span>
|
|
||||||
{{ $t('workbenchesSetup.setNum') }}
|
|
||||||
<span class="text-[10px] text-slate-400 font-normal ml-1">({{ $t('workbenchesSetup.prompt') }})</span>
|
|
||||||
</h4>
|
|
||||||
<div class="space-y-3">
|
|
||||||
<div class="flex gap-2">
|
|
||||||
<button @click="isLimit = true" :disabled="!pyData.isStart"
|
|
||||||
class="flex-1 px-3 py-2 text-xs font-semibold rounded-md border transition-colors"
|
|
||||||
:class="isLimit ? 'bg-primary text-white border-primary' : 'bg-white text-slate-600 border-slate-200 hover:border-primary/50'">
|
|
||||||
{{ $t('workbenchesSetup.setHostNum') }}
|
|
||||||
</button>
|
|
||||||
<button @click="isLimit = false" :disabled="!pyData.isStart"
|
|
||||||
class="flex-1 px-3 py-2 text-xs font-semibold rounded-md border transition-colors"
|
|
||||||
:class="!isLimit ? 'bg-slate-500 text-white border-slate-500' : 'bg-white text-slate-600 border-slate-200 hover:border-slate-400'">
|
|
||||||
{{ $t('workbenchesSetup.unlimitedQuantity') }}
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
<div v-if="isLimit"
|
|
||||||
class="flex shadow-sm rounded-lg overflow-hidden border border-slate-200 dark:border-slate-700">
|
|
||||||
<input
|
|
||||||
class="flex-1 px-4 py-2 text-sm bg-white dark:bg-slate-900 border-none outline-none focus:ring-0 disabled:bg-slate-100"
|
|
||||||
type="number" v-model="hostNum" :disabled="!pyData.isStart" />
|
|
||||||
<span
|
|
||||||
class="bg-slate-100 dark:bg-slate-800 px-3 py-2 text-xs font-medium text-slate-500 w-16 flex items-center justify-center border-l border-slate-200 dark:border-slate-700">{{
|
|
||||||
$t('workbenchesSetup.num') }}</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div
|
|
||||||
class="flex flex-col lg:flex-row items-center justify-between gap-6 pt-4 border-t border-slate-100 dark:border-slate-800">
|
|
||||||
<div class="flex items-center gap-6">
|
|
||||||
<div class="flex items-center gap-2 cursor-pointer group" @click="toggleFilter('filterGame')">
|
|
||||||
<span class="w-4 h-4 rounded border-2 flex items-center justify-center transition-all"
|
|
||||||
:class="pyData.filterGame ? 'bg-primary border-primary' : 'bg-white border-slate-300'">
|
|
||||||
<span v-if="pyData.filterGame" class="material-icons-round text-white text-xs">check</span>
|
|
||||||
</span>
|
</span>
|
||||||
<span
|
|
||||||
class="text-sm text-slate-600 dark:text-slate-400 group-hover:text-primary transition-colors">过滤游戏主播</span>
|
<img style="height: 20px;" v-if="isWifi" src="@/assets/wifi.png">
|
||||||
</div>
|
|
||||||
<div class="flex items-center gap-2 cursor-pointer group" @click="toggleFilter('filterSelling')">
|
<span class="inline-country">
|
||||||
<span class="w-4 h-4 rounded border-2 flex items-center justify-center transition-all"
|
<span style="color: black;">指定国家</span>
|
||||||
:class="pyData.filterSelling ? 'bg-primary border-primary' : 'bg-white border-slate-300'">
|
<el-select v-model="country_info" class="country-select" placeholder="全部" size="small">
|
||||||
<span v-if="pyData.filterSelling" class="material-icons-round text-white text-xs">check</span>
|
<el-option :label="'全部'" :value="'地区全部'" />
|
||||||
|
<el-option v-for="(item, index) in country_Lst" :key="index" :label="item"
|
||||||
|
:value="item" />
|
||||||
|
</el-select>
|
||||||
</span>
|
</span>
|
||||||
<span
|
|
||||||
class="text-sm text-slate-600 dark:text-slate-400 group-hover:text-primary transition-colors">过滤带货主播</span>
|
|
||||||
</div>
|
|
||||||
<div class="flex items-center gap-2 cursor-pointer group" @click="toggleFilter('rankingList')">
|
|
||||||
<span class="w-4 h-4 rounded border-2 flex items-center justify-center transition-all"
|
|
||||||
:class="pyData.rankingList ? 'bg-primary border-primary' : 'bg-white border-slate-300'">
|
|
||||||
<span v-if="pyData.rankingList" class="material-icons-round text-white text-xs">check</span>
|
|
||||||
</span>
|
|
||||||
<span
|
|
||||||
class="text-sm text-slate-600 dark:text-slate-400 group-hover:text-primary transition-colors">过滤排行榜单</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="mt-6 text-center">
|
</div>
|
||||||
<button v-if="pyData.isStart" @click="submit"
|
</template>
|
||||||
class="bg-slate-900 dark:bg-primary hover:scale-[1.02] active:scale-[0.98] text-white px-10 py-3 rounded-xl font-bold text-lg shadow-xl shadow-slate-900/10 dark:shadow-primary/20 transition-all flex items-center gap-2 mx-auto">
|
<el-row :gutter="24">
|
||||||
<span class="material-icons-round">bolt</span>
|
<el-col :span="6">
|
||||||
{{ $t('workbenchesSetup.start') }}
|
<div class="input-group">
|
||||||
</button>
|
<label>{{ $t('workbenchesSetup.setCoinsNum') }}</label>
|
||||||
<button v-else @click="unsubmit"
|
<el-input type='number' v-model="pyData.gold.min" :min="0" :max="pyData.gold.max - 1"
|
||||||
class="bg-red-500 hover:bg-red-600 hover:scale-[1.02] active:scale-[0.98] text-white px-12 py-4 rounded-xl font-bold text-lg shadow-xl shadow-red-500/20 transition-all flex items-center gap-3 mx-auto">
|
:placeholder="$t('workbenchesSetup.minCoinsNum')" style="width: 100%"
|
||||||
<span class="material-icons-round">stop</span>
|
:disabled="!pyData.isStart">
|
||||||
{{ $t('workbenchesSetup.stop') }}
|
<template #prepend>{{ $t('workbenchesSetup.minCoinsNum') }}</template>
|
||||||
</button>
|
</el-input>
|
||||||
<p class="mt-4 text-xs font-medium text-emerald-600 dark:text-emerald-400">
|
<el-input type='number' v-model="pyData.gold.max" :min="pyData.gold.min + 1" :max="100"
|
||||||
|
:placeholder="$t('workbenchesSetup.maxCoinsNum')" style="width: 100%; margin-top: 10px"
|
||||||
|
:disabled="!pyData.isStart">
|
||||||
|
<template #prepend>{{ $t('workbenchesSetup.maxCoinsNum') }}</template>
|
||||||
|
</el-input>
|
||||||
|
</div>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="6">
|
||||||
|
<div class="input-group">
|
||||||
|
<label>{{ $t('workbenchesSetup.setFansNum') }}</label>
|
||||||
|
<el-input type='number' v-model="pyData.fans.min" :min="0" :max="pyData.fans.max - 1"
|
||||||
|
:placeholder="$t('workbenchesSetup.minFansNum')" style="width: 100%"
|
||||||
|
:disabled="!pyData.isStart">
|
||||||
|
<template #prepend>{{ $t('workbenchesSetup.minFansNum') }}</template>
|
||||||
|
</el-input>
|
||||||
|
<el-input type='number' v-model="pyData.fans.max" :min="pyData.fans.min + 1" :max="100"
|
||||||
|
:placeholder="$t('workbenchesSetup.maxFansNum')" style="width: 100%; margin-top: 10px"
|
||||||
|
:disabled="!pyData.isStart">
|
||||||
|
<template #prepend>{{ $t('workbenchesSetup.maxFansNum') }}</template>
|
||||||
|
</el-input>
|
||||||
|
</div>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="6">
|
||||||
|
<div class="input-group">
|
||||||
|
<label>{{ $t('workbenchesSetup.setQuery') }}</label>
|
||||||
|
<!-- <el-input type='number' v-model="pyData.frequency.hour" @input="handleInputHour" -->
|
||||||
|
<el-input type='number' v-model="pyData.frequency.hour"
|
||||||
|
:placeholder="$t('workbenchesSetup.hour')" style="width: 100%"
|
||||||
|
:disabled="!pyData.isStart">
|
||||||
|
<template #append>{{ $t('workbenchesSetup.hour') }}</template>
|
||||||
|
</el-input>
|
||||||
|
<!-- <el-input type='number' v-model="pyData.frequency.day" @input="handleInputDay" -->
|
||||||
|
<el-input type='number' v-model="pyData.frequency.day"
|
||||||
|
:placeholder="$t('workbenchesSetup.hour24')" style="width: 100%; margin-top: 10px"
|
||||||
|
:disabled="!pyData.isStart">
|
||||||
|
<template #append>{{ $t('workbenchesSetup.hour24') }}</template>
|
||||||
|
</el-input>
|
||||||
|
</div>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="6">
|
||||||
|
<div class="input-group">
|
||||||
|
<label>{{ $t('workbenchesSetup.setNum') }}</label>
|
||||||
|
<label style="color: #00000070; font-size: 15px;">({{ $t('workbenchesSetup.prompt')
|
||||||
|
}})</label>
|
||||||
|
<el-button type="primary" @click="isLimit = true" :disabled="!pyData.isStart">{{
|
||||||
|
$t('workbenchesSetup.setHostNum')
|
||||||
|
}}</el-button>
|
||||||
|
<el-button type="info" @click="isLimit = false" :disabled="!pyData.isStart">{{
|
||||||
|
$t('workbenchesSetup.unlimitedQuantity')
|
||||||
|
}}</el-button>
|
||||||
|
<!-- <el-input type='number' v-model="pyData.frequency.hour" @input="handleInputHour" -->
|
||||||
|
<div v-if="isLimit" class="center-justify">
|
||||||
|
<el-input type='number' v-model="hostNum" :placeholder="$t('workbenchesSetup.num')"
|
||||||
|
style="width: 100% ;" :disabled="!pyData.isStart">
|
||||||
|
<template #append>{{ $t('workbenchesSetup.num') }}</template>
|
||||||
|
</el-input>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</el-col>
|
||||||
|
</el-row>
|
||||||
|
<div class="center-line" style="margin-top: 0px; text-align: center">
|
||||||
|
<div class="center-justify">
|
||||||
|
<el-checkbox @click="console.log(pyData)" :disabled="!pyData.isStart"
|
||||||
|
v-model="pyData.filterGame" label="过滤游戏主播" border />
|
||||||
|
<el-checkbox @click="console.log(pyData)" :disabled="!pyData.isStart"
|
||||||
|
v-model="pyData.filterSelling" label="过滤带货主播" border />
|
||||||
|
<el-checkbox @click="console.log(pyData)" :disabled="!pyData.isStart"
|
||||||
|
v-model="pyData.rankingList" label="排行榜" border />
|
||||||
|
</div>
|
||||||
|
<el-button class="submit-button" :disabled="false" v-show="pyData.isStart" type="primary"
|
||||||
|
@click="submit">{{
|
||||||
|
$t('workbenchesSetup.start') }}</el-button>
|
||||||
|
<el-button v-show="!pyData.isStart" type="danger" @click="unsubmit">{{
|
||||||
|
$t('workbenchesSetup.stop') }}</el-button>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</el-card>
|
||||||
|
</div>
|
||||||
|
<div style="color: green;">
|
||||||
到期时间: {{ timestampToTime(expiredTime) }}
|
到期时间: {{ timestampToTime(expiredTime) }}
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
@@ -293,7 +183,7 @@ import { tkaccountuseinfo, getExpiredTime } from '@/api/account'
|
|||||||
import { useI18n } from 'vue-i18n'
|
import { useI18n } from 'vue-i18n'
|
||||||
const { locale } = useI18n()
|
const { locale } = useI18n()
|
||||||
//导入python交互方法
|
//导入python交互方法
|
||||||
const { fetchDataConfig, fetchDataCount, loginBackStage, loginTikTok, backStageloginStatus, backStageloginStatusCopy, getTkLoginStatus } = usePythonBridge();
|
const { fetchDataConfig, fetchDataCount, loginBackStage, loginTikTok, backStageloginStatus, backStageloginStatusCopy } = usePythonBridge();
|
||||||
|
|
||||||
|
|
||||||
//ip国家
|
//ip国家
|
||||||
@@ -318,10 +208,6 @@ let hostData = ref({
|
|||||||
|
|
||||||
//账号是否登陆中
|
//账号是否登陆中
|
||||||
let isLogin = ref([false, false]);
|
let isLogin = ref([false, false]);
|
||||||
//TK登录状态
|
|
||||||
let isTkLoggedIn = ref(false);
|
|
||||||
//TK状态轮询定时器
|
|
||||||
let tkStatusTimer = ref(null);
|
|
||||||
//设置状态轮询定时器
|
//设置状态轮询定时器
|
||||||
let statusTimer = ref(null);
|
let statusTimer = ref(null);
|
||||||
let statusTimerCopy = ref(null);
|
let statusTimerCopy = ref(null);
|
||||||
@@ -514,7 +400,7 @@ const submit = () => {
|
|||||||
isStart: true,
|
isStart: true,
|
||||||
filterSelling: pyData.value.filterSelling,
|
filterSelling: pyData.value.filterSelling,
|
||||||
filterGame: pyData.value.filterGame,
|
filterGame: pyData.value.filterGame,
|
||||||
rankingList: !pyData.value.rankingList,
|
rankingList: pyData.value.rankingList,
|
||||||
country: countryData.value,
|
country: countryData.value,
|
||||||
tenantId: getUser().tenantId,
|
tenantId: getUser().tenantId,
|
||||||
userId: getUser().id,
|
userId: getUser().id,
|
||||||
@@ -525,14 +411,15 @@ const submit = () => {
|
|||||||
//开启查询次数
|
//开启查询次数
|
||||||
getHostTimer.value = setInterval(() => {
|
getHostTimer.value = setInterval(() => {
|
||||||
fetchDataCount().then((res) => {
|
fetchDataCount().then((res) => {
|
||||||
hostData.value = JSON.parse(res);
|
if (res) {
|
||||||
|
hostData.value = res;
|
||||||
if (isLimit.value) {
|
if (isLimit.value) {
|
||||||
if (hostData.value.canInvitationCount >= hostNum.value) {
|
if (hostData.value.canInvitationCount >= hostNum.value) {
|
||||||
unsubmit();
|
unsubmit();
|
||||||
alert('爬取完毕')
|
alert('爬取完毕')
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
})
|
})
|
||||||
}, 1000);
|
}, 1000);
|
||||||
getNumTimer.value = setInterval(() => {
|
getNumTimer.value = setInterval(() => {
|
||||||
@@ -566,7 +453,7 @@ const unsubmit = () => {
|
|||||||
isStart: false,
|
isStart: false,
|
||||||
filterSelling: pyData.value.filterSelling,
|
filterSelling: pyData.value.filterSelling,
|
||||||
filterGame: pyData.value.filterGame,
|
filterGame: pyData.value.filterGame,
|
||||||
rankingList: !pyData.value.rankingList,
|
rankingList: pyData.value.rankingList,
|
||||||
country: countryData.value,
|
country: countryData.value,
|
||||||
tenantId: getUser().tenantId,
|
tenantId: getUser().tenantId,
|
||||||
userId: getUser().id,
|
userId: getUser().id,
|
||||||
@@ -593,12 +480,6 @@ const reset = () => {
|
|||||||
pyData.value.frequency = { hour: 0, day: 0 };
|
pyData.value.frequency = { hour: 0, day: 0 };
|
||||||
};
|
};
|
||||||
|
|
||||||
// 切换过滤选项 (用于Electron环境下的即时响应)
|
|
||||||
const toggleFilter = (filterName) => {
|
|
||||||
if (!pyData.value.isStart) return; // 如果已启动则不允许修改
|
|
||||||
pyData.value[filterName] = !pyData.value[filterName];
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
const loginTK = (index) => {
|
const loginTK = (index) => {
|
||||||
setTkUser(tkData.value)
|
setTkUser(tkData.value)
|
||||||
@@ -627,27 +508,11 @@ const openTK = () => {
|
|||||||
// console.log(isTk.value)
|
// console.log(isTk.value)
|
||||||
loginTikTok();
|
loginTikTok();
|
||||||
|
|
||||||
// 开始轮询TK登录状态
|
|
||||||
if (tkStatusTimer.value) {
|
|
||||||
clearInterval(tkStatusTimer.value);
|
|
||||||
}
|
|
||||||
tkStatusTimer.value = setInterval(() => {
|
|
||||||
checkTkLoginStatus();
|
|
||||||
}, 3000);
|
|
||||||
}
|
|
||||||
|
|
||||||
// 检查TK登录状态
|
|
||||||
const checkTkLoginStatus = () => {
|
|
||||||
getTkLoginStatus().then((res) => {
|
|
||||||
isTkLoggedIn.value = res === true || res === 'true';
|
|
||||||
}).catch(() => {
|
|
||||||
isTkLoggedIn.value = false;
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function getloginStatus() {
|
function getloginStatus() {
|
||||||
backStageloginStatus().then((res) => {
|
backStageloginStatus().then((res) => {
|
||||||
const data = JSON.parse(res);
|
const data = res;
|
||||||
tkData.value[data.index].code = data.code
|
tkData.value[data.index].code = data.code
|
||||||
|
|
||||||
if (data.code == 1) {
|
if (data.code == 1) {
|
||||||
@@ -660,7 +525,7 @@ function getloginStatus() {
|
|||||||
}
|
}
|
||||||
function getloginStatusCopy() {
|
function getloginStatusCopy() {
|
||||||
backStageloginStatusCopy().then((res) => {
|
backStageloginStatusCopy().then((res) => {
|
||||||
const data = JSON.parse(res);
|
const data = res;
|
||||||
tkData.value[data.index].code = data.code
|
tkData.value[data.index].code = data.code
|
||||||
|
|
||||||
if (data.code == 1) {
|
if (data.code == 1) {
|
||||||
@@ -832,46 +697,257 @@ const checkVPN = async () => {
|
|||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped>
|
<style scoped lang="less">
|
||||||
/*
|
.container {
|
||||||
Most styles are replaced by Tailwind utility classes.
|
margin: 0 auto;
|
||||||
We can keep specific overrides or custom animations here if needed.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* Element Plus 输入框统一样式 */
|
|
||||||
.el-input-custom :deep(.el-input__wrapper) {
|
|
||||||
background-color: white;
|
|
||||||
border: 1px solid rgb(226, 232, 240);
|
|
||||||
border-radius: 0.5rem;
|
|
||||||
padding: 0.5rem 1rem;
|
|
||||||
box-shadow: none;
|
|
||||||
transition: all 0.15s ease;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.el-input-custom :deep(.el-input__wrapper:hover) {
|
.workbenches {
|
||||||
border-color: rgb(203, 213, 225);
|
padding: 45px 29px 22px 27px;
|
||||||
|
|
||||||
|
/* 页面无法选中 */
|
||||||
|
-webkit-user-select: none;
|
||||||
|
-moz-user-select: none;
|
||||||
|
-ms-user-select: none;
|
||||||
|
user-select: none;
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.el-input-custom :deep(.el-input__wrapper.is-focus) {
|
.box-card {
|
||||||
border-color: var(--el-color-primary);
|
// width: 1240px;
|
||||||
box-shadow: 0 0 0 2px rgba(59, 130, 246, 0.2);
|
height: 436px;
|
||||||
|
background: #FFFFFF;
|
||||||
|
box-shadow: 0px 0px 21px 0px rgba(183, 183, 183, 0.33);
|
||||||
|
border-radius: 24px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.el-input-custom :deep(.el-input__inner) {
|
.box-card-num1 {
|
||||||
font-size: 0.875rem;
|
|
||||||
|
width: 197px;
|
||||||
|
height: 321px;
|
||||||
|
background: #FFFFFF;
|
||||||
|
box-shadow: 0px 0px 21px 0px rgba(183, 183, 183, 0.33);
|
||||||
|
border-radius: 24px;
|
||||||
|
// padding-top: 60px;
|
||||||
|
box-sizing: border-box;
|
||||||
|
|
||||||
|
div {
|
||||||
|
height: 20%;
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-around;
|
||||||
|
align-items: center;
|
||||||
|
|
||||||
|
color: #8D8E8E;
|
||||||
|
|
||||||
|
span {
|
||||||
|
color: #000;
|
||||||
|
padding-left: 10px;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.el-input-custom :deep(.el-input__wrapper.is-disabled) {
|
.box-card-num {
|
||||||
opacity: 0.5;
|
width: 897px;
|
||||||
|
height: 145px;
|
||||||
|
background: #FFFFFF;
|
||||||
|
box-shadow: 0px 0px 21px 0px rgba(183, 183, 183, 0.33);
|
||||||
|
border-radius: 24px;
|
||||||
|
margin-bottom: 30px;
|
||||||
|
|
||||||
|
padding-top: 18px;
|
||||||
|
box-sizing: border-box;
|
||||||
|
|
||||||
|
.todayCount {
|
||||||
|
padding: 15px 21px;
|
||||||
|
font-size: 14px;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 暗色模式支持 */
|
.from-input-item {
|
||||||
.dark .el-input-custom :deep(.el-input__wrapper) {
|
display: flex;
|
||||||
background-color: rgb(30, 41, 59);
|
|
||||||
border-color: rgb(51, 65, 85);
|
.from-input-item-title {
|
||||||
|
color: #000000;
|
||||||
|
font-size: 14px;
|
||||||
|
font-weight: 500;
|
||||||
|
width: 100px;
|
||||||
|
height: 50px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.dark .el-input-custom :deep(.el-input__wrapper:hover) {
|
.loginButton {
|
||||||
border-color: rgb(71, 85, 105);
|
width: 100%;
|
||||||
|
height: 40px;
|
||||||
|
color: #ffffff;
|
||||||
|
font-size: 16px;
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
.loginState {
|
||||||
|
width: 15px;
|
||||||
|
height: 15px;
|
||||||
|
border-radius: 50%;
|
||||||
|
background-color: #b90000;
|
||||||
|
margin-left: 15px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.card-header {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: center;
|
||||||
|
|
||||||
|
.card-header-right {
|
||||||
|
margin-right: 70px;
|
||||||
|
display: inline-flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 12px;
|
||||||
|
/* 各个块之间的间距 */
|
||||||
|
white-space: nowrap;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* 整个右侧区域不换行 */
|
||||||
|
span {
|
||||||
|
color: #0013b9;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.inline-country {
|
||||||
|
display: inline-flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 6px;
|
||||||
|
/* “指定国家” 和 select 的间距 */
|
||||||
|
}
|
||||||
|
|
||||||
|
.country-select {
|
||||||
|
min-width: 120px;
|
||||||
|
/* 防止 select 太窄,文字被挤没 */
|
||||||
|
}
|
||||||
|
|
||||||
|
span {
|
||||||
|
font-family: Source Han Sans SC;
|
||||||
|
font-weight: 400;
|
||||||
|
font-size: 20px;
|
||||||
|
color: #2D2727;
|
||||||
|
line-height: 37px;
|
||||||
|
|
||||||
|
img {
|
||||||
|
margin-right: 16px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.input-group {
|
||||||
|
margin-bottom: 20px;
|
||||||
|
height: 100%;
|
||||||
|
|
||||||
|
.el-input {
|
||||||
|
margin: 22px 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
.open-login {
|
||||||
|
width: 100px;
|
||||||
|
height: 47px;
|
||||||
|
background: @btn-bg-color;
|
||||||
|
border-radius: 10px;
|
||||||
|
border: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.reset-button {
|
||||||
|
width: 132px;
|
||||||
|
height: 47px;
|
||||||
|
background: @btn-bg-color;
|
||||||
|
border-radius: 10px;
|
||||||
|
|
||||||
|
font-family: Source Han Sans SC;
|
||||||
|
font-weight: 400;
|
||||||
|
font-size: 18px;
|
||||||
|
color: #FFFFFF;
|
||||||
|
|
||||||
|
margin-left: 50px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.submit-button {
|
||||||
|
width: 160px;
|
||||||
|
height: 47px;
|
||||||
|
background: @bg-color;
|
||||||
|
border-radius: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.center-line {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
// justify-content: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.center-justify {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-around;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.center-align {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
.center-flex {
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
||||||
|
|
||||||
|
<style scoped lang="less">
|
||||||
|
::v-deep(.el-input-group__prepend) {
|
||||||
|
background: @bg-color-light;
|
||||||
|
border-radius: 10px 0px 0px 10px;
|
||||||
|
border: 1px solid #B7CEC5;
|
||||||
|
font-family: Source Han Sans SC;
|
||||||
|
font-weight: 400;
|
||||||
|
font-size: 18px;
|
||||||
|
color: #FFFFFF;
|
||||||
|
line-height: 37px;
|
||||||
|
}
|
||||||
|
|
||||||
|
::v-deep(.el-input-group__append) {
|
||||||
|
background: @bg-color-light;
|
||||||
|
border-radius: 0px 10px 10px 0px;
|
||||||
|
border: 1px solid #B7CEC5;
|
||||||
|
font-family: Source Han Sans SC;
|
||||||
|
font-weight: 400;
|
||||||
|
font-size: 18px;
|
||||||
|
color: #FFFFFF;
|
||||||
|
line-height: 37px;
|
||||||
|
}
|
||||||
|
|
||||||
|
::v-deep(.el-input__wrapper) {
|
||||||
|
width: 218px;
|
||||||
|
height: 44px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.el-input {
|
||||||
|
width: 200px;
|
||||||
|
height: 48px;
|
||||||
|
background: #FFFFFF;
|
||||||
|
border-radius: 10px;
|
||||||
|
border: 1px solid #B7CEC5;
|
||||||
|
}
|
||||||
|
|
||||||
|
.el-checkbox {
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
/* 水平居中 */
|
||||||
|
align-items: center;
|
||||||
|
/* 垂直居中 */
|
||||||
|
/* 示例高度,根据需要调整 */
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
@@ -1,440 +0,0 @@
|
|||||||
<!DOCTYPE html>
|
|
||||||
<html lang="zh-CN">
|
|
||||||
|
|
||||||
<head>
|
|
||||||
<meta charset="utf-8" />
|
|
||||||
<meta content="width=device-width, initial-scale=1.0" name="viewport" />
|
|
||||||
<title>Yolo Assistant - Modern Light-Tech Dashboard</title>
|
|
||||||
<link href="https://fonts.googleapis.com" rel="preconnect" />
|
|
||||||
<link crossorigin="" href="https://fonts.gstatic.com" rel="preconnect" />
|
|
||||||
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700&display=swap"
|
|
||||||
rel="stylesheet" />
|
|
||||||
<link href="https://fonts.googleapis.com/icon?family=Material+Icons+Round" rel="stylesheet" />
|
|
||||||
<script src="https://cdn.tailwindcss.com?plugins=forms,typography"></script>
|
|
||||||
<script>
|
|
||||||
tailwind.config = {
|
|
||||||
darkMode: "class",
|
|
||||||
theme: {
|
|
||||||
extend: {
|
|
||||||
colors: {
|
|
||||||
primary: "#0052CC",
|
|
||||||
"background-light": "#F4F7FA",
|
|
||||||
"background-dark": "#0B1120",
|
|
||||||
"tech-blue": "#E3F2FD",
|
|
||||||
"tech-green": "#E8F5E9",
|
|
||||||
"tech-orange": "#FFF3E0",
|
|
||||||
},
|
|
||||||
fontFamily: {
|
|
||||||
display: ["Inter", "system-ui", "sans-serif"],
|
|
||||||
},
|
|
||||||
borderRadius: {
|
|
||||||
DEFAULT: "12px",
|
|
||||||
'xl': '20px',
|
|
||||||
},
|
|
||||||
boxShadow: {
|
|
||||||
'soft-inner': 'inset 0 2px 4px 0 rgba(0, 0, 0, 0.05)',
|
|
||||||
'premium': '0 10px 25px -5px rgba(0, 0, 0, 0.04), 0 8px 10px -6px rgba(0, 0, 0, 0.04)',
|
|
||||||
}
|
|
||||||
},
|
|
||||||
},
|
|
||||||
};
|
|
||||||
</script>
|
|
||||||
<style>
|
|
||||||
body {
|
|
||||||
font-family: 'Inter', sans-serif;
|
|
||||||
}
|
|
||||||
|
|
||||||
.glass-card {
|
|
||||||
background: rgba(255, 255, 255, 0.8);
|
|
||||||
backdrop-filter: blur(12px);
|
|
||||||
border: 1px solid rgba(255, 255, 255, 0.4);
|
|
||||||
}
|
|
||||||
|
|
||||||
.sidebar-active {
|
|
||||||
background: white;
|
|
||||||
color: #0052CC !important;
|
|
||||||
border-radius: 40px 0 0 40px;
|
|
||||||
position: relative;
|
|
||||||
}
|
|
||||||
|
|
||||||
.sidebar-active::after {
|
|
||||||
content: '';
|
|
||||||
position: absolute;
|
|
||||||
right: -20px;
|
|
||||||
top: 0;
|
|
||||||
bottom: 0;
|
|
||||||
width: 20px;
|
|
||||||
background: white;
|
|
||||||
}
|
|
||||||
|
|
||||||
.sidebar-active::before {
|
|
||||||
content: '';
|
|
||||||
position: absolute;
|
|
||||||
right: 0;
|
|
||||||
top: -40px;
|
|
||||||
width: 40px;
|
|
||||||
height: 40px;
|
|
||||||
border-radius: 50%;
|
|
||||||
box-shadow: 20px 20px 0 0 white;
|
|
||||||
z-index: 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
.sidebar-active-footer::before {
|
|
||||||
content: '';
|
|
||||||
position: absolute;
|
|
||||||
right: 0;
|
|
||||||
bottom: -40px;
|
|
||||||
width: 40px;
|
|
||||||
height: 40px;
|
|
||||||
border-radius: 50%;
|
|
||||||
box-shadow: 20px -20px 0 0 white;
|
|
||||||
z-index: 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
::-webkit-scrollbar {
|
|
||||||
width: 6px;
|
|
||||||
}
|
|
||||||
|
|
||||||
::-webkit-scrollbar-track {
|
|
||||||
background: transparent;
|
|
||||||
}
|
|
||||||
|
|
||||||
::-webkit-scrollbar-thumb {
|
|
||||||
background: #CBD5E1;
|
|
||||||
border-radius: 10px;
|
|
||||||
}
|
|
||||||
|
|
||||||
::-webkit-scrollbar-thumb:hover {
|
|
||||||
background: #94A3B8;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
</head>
|
|
||||||
|
|
||||||
<body class="bg-slate-900 font-display text-slate-900 antialiased overflow-hidden">
|
|
||||||
<div class="flex h-screen">
|
|
||||||
<aside class="w-64 flex flex-col pt-8 pb-10 bg-slate-900 shrink-0">
|
|
||||||
<div class="px-8 mb-12">
|
|
||||||
<div class="flex items-center gap-2">
|
|
||||||
<span class="text-3xl font-bold tracking-tighter text-white">yolo</span>
|
|
||||||
<span
|
|
||||||
class="px-2 py-0.5 text-xs font-semibold tracking-wider text-slate-900 bg-white rounded uppercase">助手</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<nav class="flex-1 space-y-2 pl-4">
|
|
||||||
<a class="flex items-center gap-4 px-6 py-4 text-slate-400 hover:text-slate-200 transition-all duration-200 group"
|
|
||||||
href="#">
|
|
||||||
<span class="material-icons-round text-2xl">grid_view</span>
|
|
||||||
<span class="font-medium">工作台</span>
|
|
||||||
</a>
|
|
||||||
<div class="relative">
|
|
||||||
<a class="sidebar-active flex items-center gap-4 px-6 py-4 text-primary transition-all duration-200"
|
|
||||||
href="#">
|
|
||||||
<span class="material-icons-round text-2xl">person_search</span>
|
|
||||||
<span class="font-medium">主播列表</span>
|
|
||||||
</a>
|
|
||||||
<div class="sidebar-active-footer"></div>
|
|
||||||
</div>
|
|
||||||
</nav>
|
|
||||||
<div class="px-8 mt-auto">
|
|
||||||
<button
|
|
||||||
class="flex items-center gap-3 text-slate-400 hover:text-red-400 transition-colors duration-200 group">
|
|
||||||
<span class="material-icons-round text-xl group-hover:rotate-12 transition-transform">logout</span>
|
|
||||||
<span class="font-medium">退出登录</span>
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</aside>
|
|
||||||
<main class="flex-1 bg-white dark:bg-slate-50 m-2 rounded-3xl shadow-2xl flex flex-col overflow-hidden">
|
|
||||||
<header class="px-8 py-6 border-b border-slate-100 dark:border-slate-200/60 bg-white/50 backdrop-blur-md">
|
|
||||||
<div class="flex flex-wrap items-center gap-4">
|
|
||||||
<div class="relative flex-1 min-w-[200px]">
|
|
||||||
<select
|
|
||||||
class="w-full bg-slate-50 border-none rounded-xl py-3 pl-4 pr-10 text-sm text-slate-600 appearance-none focus:ring-2 focus:ring-primary/20 shadow-soft-inner">
|
|
||||||
<option>选择国家</option>
|
|
||||||
<option>哈萨克斯坦</option>
|
|
||||||
<option>土库曼斯坦</option>
|
|
||||||
<option>摩尔多瓦</option>
|
|
||||||
</select>
|
|
||||||
<span
|
|
||||||
class="material-icons-round absolute right-3 top-1/2 -translate-y-1/2 text-slate-400 pointer-events-none">expand_more</span>
|
|
||||||
</div>
|
|
||||||
<div class="relative flex-1 min-w-[200px]">
|
|
||||||
<span
|
|
||||||
class="material-icons-round absolute left-3 top-1/2 -translate-y-1/2 text-slate-400 text-sm">calendar_today</span>
|
|
||||||
<input
|
|
||||||
class="w-full bg-slate-50 border-none rounded-xl py-3 pl-10 pr-4 text-sm text-slate-600 focus:ring-2 focus:ring-primary/20 shadow-soft-inner"
|
|
||||||
placeholder="选择查询时间" type="text" />
|
|
||||||
</div>
|
|
||||||
<div class="relative flex-[1.5] min-w-[240px]">
|
|
||||||
<input
|
|
||||||
class="w-full bg-slate-50 border-none rounded-xl py-3 px-4 text-sm text-slate-600 focus:ring-2 focus:ring-primary/20 shadow-soft-inner"
|
|
||||||
placeholder="请输入主播id" type="text" />
|
|
||||||
</div>
|
|
||||||
<div class="flex items-center gap-2 ml-auto">
|
|
||||||
<button
|
|
||||||
class="bg-primary hover:bg-blue-700 text-white px-8 py-3 rounded-xl font-medium text-sm transition-all shadow-lg shadow-primary/20 flex items-center gap-2">
|
|
||||||
<span class="material-icons-round text-sm">search</span>
|
|
||||||
查询
|
|
||||||
</button>
|
|
||||||
<button class="bg-slate-100 hover:bg-slate-200 text-slate-600 p-3 rounded-xl transition-all">
|
|
||||||
<span class="material-icons-round">tune</span>
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</header>
|
|
||||||
<div class="flex-1 overflow-auto p-8">
|
|
||||||
<table class="w-full text-left border-separate border-spacing-0">
|
|
||||||
<thead>
|
|
||||||
<tr class="text-slate-400 text-xs font-semibold uppercase tracking-wider">
|
|
||||||
<th class="pb-4 pl-4 font-normal"><input
|
|
||||||
class="rounded border-slate-300 text-primary focus:ring-primary/20"
|
|
||||||
type="checkbox" /></th>
|
|
||||||
<th class="pb-4 font-semibold">主播ID</th>
|
|
||||||
<th class="pb-4 font-semibold">等级</th>
|
|
||||||
<th class="pb-4 font-semibold">邀请类型</th>
|
|
||||||
<th class="pb-4 font-semibold">数据查看</th>
|
|
||||||
<th class="pb-4 font-semibold">国家</th>
|
|
||||||
<th class="pb-4 font-semibold">创建时间</th>
|
|
||||||
<th class="pb-4 font-semibold">主播金币</th>
|
|
||||||
<th class="pb-4 font-semibold text-right pr-4">操作</th>
|
|
||||||
</tr>
|
|
||||||
</thead>
|
|
||||||
<tbody class="text-sm text-slate-600">
|
|
||||||
<tr class="group hover:bg-slate-50/80 transition-colors">
|
|
||||||
<td class="py-5 pl-4 border-b border-slate-50 group-last:border-none">
|
|
||||||
<input class="rounded border-slate-300 text-primary focus:ring-primary/20"
|
|
||||||
type="checkbox" />
|
|
||||||
</td>
|
|
||||||
<td class="py-5 border-b border-slate-50 group-last:border-none">
|
|
||||||
<span
|
|
||||||
class="font-medium text-slate-900 border-b border-transparent group-hover:border-primary/30 transition-all cursor-pointer">kisimisi1990</span>
|
|
||||||
</td>
|
|
||||||
<td class="py-5 border-b border-slate-50 group-last:border-none">D5</td>
|
|
||||||
<td class="py-5 border-b border-slate-50 group-last:border-none">
|
|
||||||
<span
|
|
||||||
class="px-3 py-1 bg-green-50 text-green-600 text-[10px] font-bold uppercase rounded-full">普票</span>
|
|
||||||
</td>
|
|
||||||
<td class="py-5 border-b border-slate-50 group-last:border-none">
|
|
||||||
<div class="flex gap-2">
|
|
||||||
<button
|
|
||||||
class="px-3 py-1.5 bg-blue-50 text-blue-600 hover:bg-blue-600 hover:text-white rounded-lg text-xs font-medium transition-all">查看场次</button>
|
|
||||||
<button
|
|
||||||
class="px-3 py-1.5 bg-sky-50 text-sky-600 hover:bg-sky-600 hover:text-white rounded-lg text-xs font-medium transition-all">查看收益</button>
|
|
||||||
</div>
|
|
||||||
</td>
|
|
||||||
<td class="py-5 border-b border-slate-50 group-last:border-none">哈萨克斯坦</td>
|
|
||||||
<td class="py-5 border-b border-slate-50 group-last:border-none">
|
|
||||||
<div class="flex flex-col">
|
|
||||||
<span>2026-01-13</span>
|
|
||||||
<span class="text-[10px] text-slate-400">20:23:52</span>
|
|
||||||
</div>
|
|
||||||
</td>
|
|
||||||
<td
|
|
||||||
class="py-5 border-b border-slate-50 group-last:border-none font-semibold text-slate-900">
|
|
||||||
1260</td>
|
|
||||||
<td class="py-5 border-b border-slate-50 group-last:border-none text-right pr-4">
|
|
||||||
<button class="p-1 hover:bg-slate-200 rounded transition-colors text-slate-400">
|
|
||||||
<span class="material-icons-round text-lg">more_horiz</span>
|
|
||||||
</button>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<tr class="group hover:bg-slate-50/80 transition-colors">
|
|
||||||
<td class="py-5 pl-4 border-b border-slate-50 group-last:border-none">
|
|
||||||
<input class="rounded border-slate-300 text-primary focus:ring-primary/20"
|
|
||||||
type="checkbox" />
|
|
||||||
</td>
|
|
||||||
<td class="py-5 border-b border-slate-50 group-last:border-none">
|
|
||||||
<span
|
|
||||||
class="font-medium text-slate-900 border-b border-transparent group-hover:border-primary/30 transition-all cursor-pointer">maga44458</span>
|
|
||||||
</td>
|
|
||||||
<td class="py-5 border-b border-slate-50 group-last:border-none">D5</td>
|
|
||||||
<td class="py-5 border-b border-slate-50 group-last:border-none">
|
|
||||||
<span
|
|
||||||
class="px-3 py-1 bg-green-50 text-green-600 text-[10px] font-bold uppercase rounded-full">普票</span>
|
|
||||||
</td>
|
|
||||||
<td class="py-5 border-b border-slate-50 group-last:border-none">
|
|
||||||
<div class="flex gap-2">
|
|
||||||
<button
|
|
||||||
class="px-3 py-1.5 bg-blue-50 text-blue-600 hover:bg-blue-600 hover:text-white rounded-lg text-xs font-medium transition-all">查看场次</button>
|
|
||||||
<button
|
|
||||||
class="px-3 py-1.5 bg-sky-50 text-sky-600 hover:bg-sky-600 hover:text-white rounded-lg text-xs font-medium transition-all">查看收益</button>
|
|
||||||
</div>
|
|
||||||
</td>
|
|
||||||
<td class="py-5 border-b border-slate-50 group-last:border-none">土库曼斯坦</td>
|
|
||||||
<td class="py-5 border-b border-slate-50 group-last:border-none">
|
|
||||||
<div class="flex flex-col">
|
|
||||||
<span>2026-01-13</span>
|
|
||||||
<span class="text-[10px] text-slate-400">20:23:52</span>
|
|
||||||
</div>
|
|
||||||
</td>
|
|
||||||
<td
|
|
||||||
class="py-5 border-b border-slate-50 group-last:border-none font-semibold text-slate-900">
|
|
||||||
3006</td>
|
|
||||||
<td class="py-5 border-b border-slate-50 group-last:border-none text-right pr-4">
|
|
||||||
<button class="p-1 hover:bg-slate-200 rounded transition-colors text-slate-400">
|
|
||||||
<span class="material-icons-round text-lg">more_horiz</span>
|
|
||||||
</button>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<tr class="group hover:bg-slate-50/80 transition-colors">
|
|
||||||
<td class="py-5 pl-4 border-b border-slate-50 group-last:border-none">
|
|
||||||
<input class="rounded border-slate-300 text-primary focus:ring-primary/20"
|
|
||||||
type="checkbox" />
|
|
||||||
</td>
|
|
||||||
<td class="py-5 border-b border-slate-50 group-last:border-none">
|
|
||||||
<span
|
|
||||||
class="font-medium text-slate-900 border-b border-transparent group-hover:border-primary/30 transition-all cursor-pointer">erke_700</span>
|
|
||||||
</td>
|
|
||||||
<td class="py-5 border-b border-slate-50 group-last:border-none">B5</td>
|
|
||||||
<td class="py-5 border-b border-slate-50 group-last:border-none">
|
|
||||||
<span
|
|
||||||
class="px-3 py-1 bg-amber-50 text-amber-600 text-[10px] font-bold uppercase rounded-full">金票</span>
|
|
||||||
</td>
|
|
||||||
<td class="py-5 border-b border-slate-50 group-last:border-none">
|
|
||||||
<div class="flex gap-2">
|
|
||||||
<button
|
|
||||||
class="px-3 py-1.5 bg-blue-50 text-blue-600 hover:bg-blue-600 hover:text-white rounded-lg text-xs font-medium transition-all">查看场次</button>
|
|
||||||
<button
|
|
||||||
class="px-3 py-1.5 bg-sky-50 text-sky-600 hover:bg-sky-600 hover:text-white rounded-lg text-xs font-medium transition-all">查看收益</button>
|
|
||||||
</div>
|
|
||||||
</td>
|
|
||||||
<td class="py-5 border-b border-slate-50 group-last:border-none">哈萨克斯坦</td>
|
|
||||||
<td class="py-5 border-b border-slate-50 group-last:border-none">
|
|
||||||
<div class="flex flex-col">
|
|
||||||
<span>2026-01-13</span>
|
|
||||||
<span class="text-[10px] text-slate-400">20:23:49</span>
|
|
||||||
</div>
|
|
||||||
</td>
|
|
||||||
<td
|
|
||||||
class="py-5 border-b border-slate-50 group-last:border-none font-semibold text-slate-900">
|
|
||||||
5572</td>
|
|
||||||
<td class="py-5 border-b border-slate-50 group-last:border-none text-right pr-4">
|
|
||||||
<button class="p-1 hover:bg-slate-200 rounded transition-colors text-slate-400">
|
|
||||||
<span class="material-icons-round text-lg">more_horiz</span>
|
|
||||||
</button>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<tr class="group hover:bg-slate-50/80 transition-colors">
|
|
||||||
<td class="py-5 pl-4 border-b border-slate-50 group-last:border-none">
|
|
||||||
<input class="rounded border-slate-300 text-primary focus:ring-primary/20"
|
|
||||||
type="checkbox" />
|
|
||||||
</td>
|
|
||||||
<td class="py-5 border-b border-slate-50 group-last:border-none">
|
|
||||||
<span
|
|
||||||
class="font-medium text-slate-900 border-b border-transparent group-hover:border-primary/30 transition-all cursor-pointer">luckystar1458</span>
|
|
||||||
</td>
|
|
||||||
<td class="py-5 border-b border-slate-50 group-last:border-none">D1</td>
|
|
||||||
<td class="py-5 border-b border-slate-50 group-last:border-none">
|
|
||||||
<span
|
|
||||||
class="px-3 py-1 bg-green-50 text-green-600 text-[10px] font-bold uppercase rounded-full">普票</span>
|
|
||||||
</td>
|
|
||||||
<td class="py-5 border-b border-slate-50 group-last:border-none">
|
|
||||||
<div class="flex gap-2">
|
|
||||||
<button
|
|
||||||
class="px-3 py-1.5 bg-blue-50 text-blue-600 hover:bg-blue-600 hover:text-white rounded-lg text-xs font-medium transition-all">查看场次</button>
|
|
||||||
<button
|
|
||||||
class="px-3 py-1.5 bg-sky-50 text-sky-600 hover:bg-sky-600 hover:text-white rounded-lg text-xs font-medium transition-all">查看收益</button>
|
|
||||||
</div>
|
|
||||||
</td>
|
|
||||||
<td class="py-5 border-b border-slate-50 group-last:border-none">摩尔多瓦</td>
|
|
||||||
<td class="py-5 border-b border-slate-50 group-last:border-none">
|
|
||||||
<div class="flex flex-col">
|
|
||||||
<span>2026-01-13</span>
|
|
||||||
<span class="text-[10px] text-slate-400">20:23:50</span>
|
|
||||||
</div>
|
|
||||||
</td>
|
|
||||||
<td
|
|
||||||
class="py-5 border-b border-slate-50 group-last:border-none font-semibold text-slate-900">
|
|
||||||
15107</td>
|
|
||||||
<td class="py-5 border-b border-slate-50 group-last:border-none text-right pr-4">
|
|
||||||
<button class="p-1 hover:bg-slate-200 rounded transition-colors text-slate-400">
|
|
||||||
<span class="material-icons-round text-lg">more_horiz</span>
|
|
||||||
</button>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<tr class="group hover:bg-slate-50/80 transition-colors">
|
|
||||||
<td class="py-5 pl-4 border-b border-slate-50 group-last:border-none">
|
|
||||||
<input class="rounded border-slate-300 text-primary focus:ring-primary/20"
|
|
||||||
type="checkbox" />
|
|
||||||
</td>
|
|
||||||
<td class="py-5 border-b border-slate-50 group-last:border-none">
|
|
||||||
<span
|
|
||||||
class="font-medium text-slate-900 border-b border-transparent group-hover:border-primary/30 transition-all cursor-pointer">boss.667b1</span>
|
|
||||||
</td>
|
|
||||||
<td class="py-5 border-b border-slate-50 group-last:border-none">C5</td>
|
|
||||||
<td class="py-5 border-b border-slate-50 group-last:border-none">
|
|
||||||
<span
|
|
||||||
class="px-3 py-1 bg-amber-50 text-amber-600 text-[10px] font-bold uppercase rounded-full">金票</span>
|
|
||||||
</td>
|
|
||||||
<td class="py-5 border-b border-slate-50 group-last:border-none">
|
|
||||||
<div class="flex gap-2">
|
|
||||||
<button
|
|
||||||
class="px-3 py-1.5 bg-blue-50 text-blue-600 hover:bg-blue-600 hover:text-white rounded-lg text-xs font-medium transition-all">查看场次</button>
|
|
||||||
<button
|
|
||||||
class="px-3 py-1.5 bg-sky-50 text-sky-600 hover:bg-sky-600 hover:text-white rounded-lg text-xs font-medium transition-all">查看收益</button>
|
|
||||||
</div>
|
|
||||||
</td>
|
|
||||||
<td class="py-5 border-b border-slate-50 group-last:border-none">哈萨克斯坦</td>
|
|
||||||
<td class="py-5 border-b border-slate-50 group-last:border-none">
|
|
||||||
<div class="flex flex-col">
|
|
||||||
<span>2026-01-13</span>
|
|
||||||
<span class="text-[10px] text-slate-400">20:23:49</span>
|
|
||||||
</div>
|
|
||||||
</td>
|
|
||||||
<td
|
|
||||||
class="py-5 border-b border-slate-50 group-last:border-none font-semibold text-slate-900">
|
|
||||||
4815</td>
|
|
||||||
<td class="py-5 border-b border-slate-50 group-last:border-none text-right pr-4">
|
|
||||||
<button class="p-1 hover:bg-slate-200 rounded transition-colors text-slate-400">
|
|
||||||
<span class="material-icons-round text-lg">more_horiz</span>
|
|
||||||
</button>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
</div>
|
|
||||||
<footer
|
|
||||||
class="px-8 py-6 border-t border-slate-100 dark:border-slate-200/60 bg-white/50 backdrop-blur-md flex flex-wrap items-center justify-between gap-4">
|
|
||||||
<div class="flex items-center gap-4">
|
|
||||||
<div class="relative">
|
|
||||||
<select
|
|
||||||
class="bg-slate-50 border-none rounded-lg py-2 pl-4 pr-10 text-sm text-slate-600 appearance-none focus:ring-2 focus:ring-primary/20 shadow-soft-inner">
|
|
||||||
<option>10/page</option>
|
|
||||||
<option>20/page</option>
|
|
||||||
<option>50/page</option>
|
|
||||||
</select>
|
|
||||||
<span
|
|
||||||
class="material-icons-round absolute right-2 top-1/2 -translate-y-1/2 text-slate-400 text-sm pointer-events-none">expand_more</span>
|
|
||||||
</div>
|
|
||||||
<span class="text-xs text-slate-400 font-medium">到期时间: <span class="text-green-600">2036-08-01
|
|
||||||
00:00:00</span></span>
|
|
||||||
</div>
|
|
||||||
<div class="flex items-center gap-1">
|
|
||||||
<button class="p-2 text-slate-400 hover:bg-slate-100 rounded-lg transition-colors">
|
|
||||||
<span class="material-icons-round text-lg">chevron_left</span>
|
|
||||||
</button>
|
|
||||||
<button
|
|
||||||
class="w-8 h-8 rounded-lg bg-slate-900 text-white text-xs font-bold transition-all shadow-md">1</button>
|
|
||||||
<button
|
|
||||||
class="w-8 h-8 rounded-lg hover:bg-slate-100 text-slate-600 text-xs font-semibold transition-all">2</button>
|
|
||||||
<button
|
|
||||||
class="w-8 h-8 rounded-lg hover:bg-slate-100 text-slate-600 text-xs font-semibold transition-all">3</button>
|
|
||||||
<button
|
|
||||||
class="w-8 h-8 rounded-lg hover:bg-slate-100 text-slate-600 text-xs font-semibold transition-all">4</button>
|
|
||||||
<button
|
|
||||||
class="w-8 h-8 rounded-lg hover:bg-slate-100 text-slate-600 text-xs font-semibold transition-all">5</button>
|
|
||||||
<button
|
|
||||||
class="w-8 h-8 rounded-lg hover:bg-slate-100 text-slate-600 text-xs font-semibold transition-all">6</button>
|
|
||||||
<span class="px-2 text-slate-400 text-xs font-bold">...</span>
|
|
||||||
<button
|
|
||||||
class="w-8 h-8 rounded-lg hover:bg-slate-100 text-slate-600 text-xs font-semibold transition-all">46</button>
|
|
||||||
<button class="p-2 text-slate-400 hover:bg-slate-100 rounded-lg transition-colors">
|
|
||||||
<span class="material-icons-round text-lg">chevron_right</span>
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</footer>
|
|
||||||
</main>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
</body>
|
|
||||||
|
|
||||||
</html>
|
|
||||||
@@ -1,88 +1,89 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="nav-container bg-background-light dark:bg-background-dark text-slate-800 dark:text-slate-200 shadow-2xl overflow-hidden" :style="containerStyle">
|
<div class="app-container">
|
||||||
<div class="flex h-full overflow-hidden">
|
<Sidebar class="noneText" @activeIndex="activeIndexFn" />
|
||||||
<Sidebar class="flex-none h-full" @activeIndex="activeIndexFn" />
|
<div class="content ">
|
||||||
<main class="flex-1 overflow-y-auto p-4 relative flex flex-col h-full bg-[#f3f5f9]">
|
<div v-show="activeIndexA == 1">
|
||||||
<div v-show="activeIndexA == 1" class="h-full">
|
|
||||||
<workbenches />
|
<workbenches />
|
||||||
</div>
|
</div>
|
||||||
<div v-show="activeIndexA == 2" class="h-full">
|
<div v-show="activeIndexA == 2">
|
||||||
<hostsList />
|
<hostsList />
|
||||||
</div>
|
</div>
|
||||||
<!-- Decorative blobs -->
|
<div style="position: absolute; bottom: 0; right: 0;">{{ version }}</div>
|
||||||
<!-- <div class="absolute -top-24 -right-24 w-64 h-64 bg-primary/5 rounded-full blur-3xl pointer-events-none"></div> -->
|
|
||||||
<!-- <div class="absolute -bottom-24 -left-24 w-64 h-64 bg-secondary/5 rounded-full blur-3xl pointer-events-none"></div> -->
|
|
||||||
|
|
||||||
<!-- <div class="absolute bottom-2 right-4 text-xs text-slate-400">{{ version }}</div> -->
|
|
||||||
</main>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
import Sidebar from '../components/Sidebar.vue';
|
import Sidebar from '../components/Sidebar.vue';
|
||||||
|
import { RouterLink, RouterView } from 'vue-router'
|
||||||
import hostsList from '@/views/hosts/hostsList.vue'
|
import hostsList from '@/views/hosts/hostsList.vue'
|
||||||
import workbenches from '@/views/hosts/workbenches.vue'
|
import workbenches from '@/views/hosts/workbenches.vue'
|
||||||
import { ref, computed, onMounted, onUnmounted } from 'vue'
|
import { ref } from 'vue'
|
||||||
|
import { getUser } from '@/utils/storage'
|
||||||
|
// import { usePythonBridge } from '@/utils/pythonBridge'
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// 设计稿尺寸
|
|
||||||
const DESIGN_WIDTH = 1600
|
|
||||||
const DESIGN_HEIGHT = 900
|
|
||||||
|
|
||||||
let activeIndexA = ref(1)
|
let activeIndexA = ref(1)
|
||||||
const version = ref('v0.1.0')
|
|
||||||
|
|
||||||
// 缩放比例
|
|
||||||
const zoomRatio = ref(1)
|
|
||||||
|
|
||||||
// 计算缩放比例
|
|
||||||
const calcZoom = () => {
|
|
||||||
const windowWidth = window.innerWidth
|
|
||||||
const windowHeight = window.innerHeight
|
|
||||||
|
|
||||||
// 根据宽高比例计算缩放值,取较小值保证完整显示
|
|
||||||
const widthRatio = windowWidth / DESIGN_WIDTH
|
|
||||||
const heightRatio = windowHeight / DESIGN_HEIGHT
|
|
||||||
|
|
||||||
zoomRatio.value = Math.min(widthRatio, heightRatio)
|
|
||||||
}
|
|
||||||
|
|
||||||
// 容器样式
|
|
||||||
const containerStyle = computed(() => ({
|
|
||||||
width: `${DESIGN_WIDTH}px`,
|
|
||||||
height: `${DESIGN_HEIGHT}px`,
|
|
||||||
zoom: zoomRatio.value
|
|
||||||
}))
|
|
||||||
|
|
||||||
function activeIndexFn(data) {
|
function activeIndexFn(data) {
|
||||||
activeIndexA.value = data
|
activeIndexA.value = data
|
||||||
console.log(data)
|
console.log(data)
|
||||||
}
|
}
|
||||||
|
|
||||||
onMounted(() => {
|
|
||||||
calcZoom()
|
|
||||||
window.addEventListener('resize', calcZoom)
|
|
||||||
})
|
|
||||||
|
|
||||||
onUnmounted(() => {
|
|
||||||
window.removeEventListener('resize', calcZoom)
|
|
||||||
})
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style>
|
<style lang="less">
|
||||||
/* Global resets if needed, but Tailwind handles most */
|
body,
|
||||||
body {
|
html {
|
||||||
margin: 0;
|
margin: 0;
|
||||||
padding: 0;
|
padding: 0;
|
||||||
background-color: #f3f5f9; /* Match background */
|
height: 100%;
|
||||||
display: flex;
|
|
||||||
justify-content: center;
|
|
||||||
align-items: center;
|
|
||||||
min-height: 100vh;
|
|
||||||
overflow: hidden;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.nav-container {
|
.app-container {
|
||||||
transform-origin: center center;
|
display: flex;
|
||||||
|
width: 1600px;
|
||||||
|
height: 900px;
|
||||||
|
background-color: @bg-color;
|
||||||
|
position: relative;
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
.noneText {
|
||||||
|
/* 页面无法选中 */
|
||||||
|
-webkit-user-select: none;
|
||||||
|
-moz-user-select: none;
|
||||||
|
-ms-user-select: none;
|
||||||
|
user-select: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sidebar {
|
||||||
|
width: 200px;
|
||||||
|
background-color: @bg-color;
|
||||||
|
padding: 20px;
|
||||||
|
/* box-shadow: 2px 0 5px rgba(0, 0, 0, 0.1); */
|
||||||
|
}
|
||||||
|
|
||||||
|
.content {
|
||||||
|
margin-left: 280px;
|
||||||
|
width: 1304px;
|
||||||
|
height: 868px;
|
||||||
|
background: #FFFFFF;
|
||||||
|
border-radius: 36px;
|
||||||
|
margin-top: 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.center-justify {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-around;
|
||||||
|
align-items: center;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
Reference in New Issue
Block a user