Compare commits
20 Commits
05cad57358
...
master
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
812fade238 | ||
|
|
84bab8b8c8 | ||
|
|
bf61508796 | ||
|
|
73d8b38f99 | ||
|
|
6959fd2d7a | ||
|
|
ea50c14175 | ||
|
|
8cabf98bd9 | ||
|
|
51ce853bde | ||
|
|
a46cbf79f6 | ||
|
|
52415dee0b | ||
|
|
01e9c26821 | ||
| 560581f1a4 | |||
| 17d2251a70 | |||
| dcd677bbab | |||
| 60f6fc4873 | |||
| 5e34aaf402 | |||
| c5fb3ea0b2 | |||
| 666e27246f | |||
| 91ee2dd7cb | |||
| 7df29e741c |
101
package-lock.json
generated
@@ -12,9 +12,10 @@
|
||||
"core-js": "^3.8.3",
|
||||
"echarts": "^5.6.0",
|
||||
"element-plus": "^2.9.7",
|
||||
"pinia": "^3.0.1",
|
||||
"pinia": "^3.0.3",
|
||||
"qwebchannel": "^6.2.0",
|
||||
"vue": "^3.2.13",
|
||||
"vue-i18n": "^9.14.5",
|
||||
"vue-router": "^4.0.3",
|
||||
"vuex": "^4.0.0"
|
||||
},
|
||||
@@ -91,6 +92,7 @@
|
||||
"integrity": "sha512-vMqyb7XCDMPvJFFOaT9kxtiRh42GwlZEg1/uIgtZshS5a/8OaduUfCi7kynKgc3Tw/6Uo2D+db9qBttghhmxwQ==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"@ampproject/remapping": "^2.2.0",
|
||||
"@babel/code-frame": "^7.26.2",
|
||||
@@ -1767,6 +1769,7 @@
|
||||
}
|
||||
],
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
},
|
||||
@@ -1790,6 +1793,7 @@
|
||||
}
|
||||
],
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
}
|
||||
@@ -1874,6 +1878,7 @@
|
||||
"integrity": "sha512-8sLjZwK0R+JlxlYcTuVnyT2v+htpdrjDOKuMcOVdYjt52Lh8hWRYpxBPoKx/Zg+bcjc3wx6fmQevMmUztS/ccA==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"cssesc": "^3.0.0",
|
||||
"util-deprecate": "^1.0.2"
|
||||
@@ -2221,6 +2226,7 @@
|
||||
"integrity": "sha512-8sLjZwK0R+JlxlYcTuVnyT2v+htpdrjDOKuMcOVdYjt52Lh8hWRYpxBPoKx/Zg+bcjc3wx6fmQevMmUztS/ccA==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"cssesc": "^3.0.0",
|
||||
"util-deprecate": "^1.0.2"
|
||||
@@ -2871,6 +2877,50 @@
|
||||
"@hapi/hoek": "^9.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@intlify/core-base": {
|
||||
"version": "9.14.5",
|
||||
"resolved": "https://registry.npmjs.org/@intlify/core-base/-/core-base-9.14.5.tgz",
|
||||
"integrity": "sha512-5ah5FqZG4pOoHjkvs8mjtv+gPKYU0zCISaYNjBNNqYiaITxW8ZtVih3GS/oTOqN8d9/mDLyrjD46GBApNxmlsA==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@intlify/message-compiler": "9.14.5",
|
||||
"@intlify/shared": "9.14.5"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 16"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/kazupon"
|
||||
}
|
||||
},
|
||||
"node_modules/@intlify/message-compiler": {
|
||||
"version": "9.14.5",
|
||||
"resolved": "https://registry.npmjs.org/@intlify/message-compiler/-/message-compiler-9.14.5.tgz",
|
||||
"integrity": "sha512-IHzgEu61/YIpQV5Pc3aRWScDcnFKWvQA9kigcINcCBXN8mbW+vk9SK+lDxA6STzKQsVJxUPg9ACC52pKKo3SVQ==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@intlify/shared": "9.14.5",
|
||||
"source-map-js": "^1.0.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 16"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/kazupon"
|
||||
}
|
||||
},
|
||||
"node_modules/@intlify/shared": {
|
||||
"version": "9.14.5",
|
||||
"resolved": "https://registry.npmjs.org/@intlify/shared/-/shared-9.14.5.tgz",
|
||||
"integrity": "sha512-9gB+E53BYuAEMhbCAxVgG38EZrk59sxBtv3jSizNL2hEWlgjBjAw1AwpLHtNaeda12pe6W20OGEa0TwuMSRbyQ==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">= 16"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/kazupon"
|
||||
}
|
||||
},
|
||||
"node_modules/@jridgewell/gen-mapping": {
|
||||
"version": "0.3.8",
|
||||
"resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.8.tgz",
|
||||
@@ -3222,6 +3272,7 @@
|
||||
"resolved": "https://registry.npmjs.org/@types/lodash-es/-/lodash-es-4.17.12.tgz",
|
||||
"integrity": "sha512-0NgftHUcV4v34VhXm8QBSftKVXtbkBG3ViCjs6+eJ5a6y6Mi/jiFGPc1sC7QK+9BFhWrURE3EOggmWaSxL9OzQ==",
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"@types/lodash": "*"
|
||||
}
|
||||
@@ -3648,6 +3699,7 @@
|
||||
"integrity": "sha512-nV7tYQLe7YsTtzFrfOMIHc5N2hp5lHG2rpYr0aNja9rNljdgcPZLyQRb2YRivTHqTv7lI962UXFURcpStHgyFw==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"@babel/helper-compilation-targets": "^7.12.16",
|
||||
"@soda/friendly-errors-webpack-plugin": "^1.8.0",
|
||||
@@ -4386,6 +4438,7 @@
|
||||
"integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"fast-deep-equal": "^3.1.1",
|
||||
"fast-json-stable-stringify": "^2.0.0",
|
||||
@@ -4912,6 +4965,7 @@
|
||||
}
|
||||
],
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"caniuse-lite": "^1.0.30001688",
|
||||
"electron-to-chromium": "^1.5.73",
|
||||
@@ -5718,6 +5772,7 @@
|
||||
"integrity": "sha512-8sLjZwK0R+JlxlYcTuVnyT2v+htpdrjDOKuMcOVdYjt52Lh8hWRYpxBPoKx/Zg+bcjc3wx6fmQevMmUztS/ccA==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"cssesc": "^3.0.0",
|
||||
"util-deprecate": "^1.0.2"
|
||||
@@ -5732,6 +5787,7 @@
|
||||
"integrity": "sha512-CTJ+AEQJjq5NzLga5pE39qdiSV56F8ywCIsqNIRF0r7BDgWsN25aazToqAFg7ZrtA/U016xudB3ffgweORxX7g==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"icss-utils": "^5.1.0",
|
||||
"postcss": "^8.4.33",
|
||||
@@ -5820,6 +5876,7 @@
|
||||
"integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"fast-deep-equal": "^3.1.3",
|
||||
"fast-uri": "^3.0.1",
|
||||
@@ -8467,13 +8524,15 @@
|
||||
"version": "4.17.21",
|
||||
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz",
|
||||
"integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==",
|
||||
"license": "MIT"
|
||||
"license": "MIT",
|
||||
"peer": true
|
||||
},
|
||||
"node_modules/lodash-es": {
|
||||
"version": "4.17.21",
|
||||
"resolved": "https://registry.npmjs.org/lodash-es/-/lodash-es-4.17.21.tgz",
|
||||
"integrity": "sha512-mKnC+QJ9pWVzv+C4/U3rRsHapFfHvQFoFB92e52xeyGMcX6/OlIl78je1u8vePzYZSkkogMPJ2yjxxsb89cxyw==",
|
||||
"license": "MIT"
|
||||
"license": "MIT",
|
||||
"peer": true
|
||||
},
|
||||
"node_modules/lodash-unified": {
|
||||
"version": "1.0.3",
|
||||
@@ -8910,6 +8969,7 @@
|
||||
"integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"fast-deep-equal": "^3.1.3",
|
||||
"fast-uri": "^3.0.1",
|
||||
@@ -9709,9 +9769,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/pinia": {
|
||||
"version": "3.0.1",
|
||||
"resolved": "https://registry.npmjs.org/pinia/-/pinia-3.0.1.tgz",
|
||||
"integrity": "sha512-WXglsDzztOTH6IfcJ99ltYZin2mY8XZCXujkYWVIJlBjqsP6ST7zw+Aarh63E1cDVYeyUcPCxPHzJpEOmzB6Wg==",
|
||||
"version": "3.0.3",
|
||||
"resolved": "https://registry.npmjs.org/pinia/-/pinia-3.0.3.tgz",
|
||||
"integrity": "sha512-ttXO/InUULUXkMHpTdp9Fj4hLpD/2AoJdmAbAeW2yu1iy1k+pkFekQXw5VpC0/5p51IOR/jDaDRfRWRnMMsGOA==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@vue/devtools-api": "^7.7.2"
|
||||
@@ -9784,6 +9844,7 @@
|
||||
}
|
||||
],
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"nanoid": "^3.3.8",
|
||||
"picocolors": "^1.1.1",
|
||||
@@ -10712,6 +10773,7 @@
|
||||
"integrity": "sha512-8sLjZwK0R+JlxlYcTuVnyT2v+htpdrjDOKuMcOVdYjt52Lh8hWRYpxBPoKx/Zg+bcjc3wx6fmQevMmUztS/ccA==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"cssesc": "^3.0.0",
|
||||
"util-deprecate": "^1.0.2"
|
||||
@@ -12880,6 +12942,7 @@
|
||||
"integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"fast-deep-equal": "^3.1.3",
|
||||
"fast-uri": "^3.0.1",
|
||||
@@ -13269,6 +13332,7 @@
|
||||
"resolved": "https://registry.npmjs.org/vue/-/vue-3.5.13.tgz",
|
||||
"integrity": "sha512-wmeiSMxkZCSc+PM2w2VRsOYAZC8GdipNFRTsLSfodVqI9mbejKeXEGr8SckuLnrQPGe3oJN5c3K0vpoU9q/wCQ==",
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"@vue/compiler-dom": "3.5.13",
|
||||
"@vue/compiler-sfc": "3.5.13",
|
||||
@@ -13292,6 +13356,26 @@
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/vue-i18n": {
|
||||
"version": "9.14.5",
|
||||
"resolved": "https://registry.npmjs.org/vue-i18n/-/vue-i18n-9.14.5.tgz",
|
||||
"integrity": "sha512-0jQ9Em3ymWngyiIkj0+c/k7WgaPO+TNzjKSNq9BvBQaKJECqn9cd9fL4tkDhB5G1QBskGl9YxxbDAhgbFtpe2g==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@intlify/core-base": "9.14.5",
|
||||
"@intlify/shared": "9.14.5",
|
||||
"@vue/devtools-api": "^6.5.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 16"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/kazupon"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"vue": "^3.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/vue-loader": {
|
||||
"version": "17.4.2",
|
||||
"resolved": "https://registry.npmjs.org/vue-loader/-/vue-loader-17.4.2.tgz",
|
||||
@@ -13431,6 +13515,7 @@
|
||||
"integrity": "sha512-UFynvx+gM44Gv9qFgj0acCQK2VE1CtdfwFdimkapco3hlPCJ/zeq73n2yVKimVbtm+TnApIugGhLJnkU6gjYXA==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"@types/eslint-scope": "^3.7.7",
|
||||
"@types/estree": "^1.0.6",
|
||||
@@ -13567,6 +13652,7 @@
|
||||
"integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"fast-deep-equal": "^3.1.3",
|
||||
"fast-uri": "^3.0.1",
|
||||
@@ -13684,6 +13770,7 @@
|
||||
"integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"fast-deep-equal": "^3.1.3",
|
||||
"fast-uri": "^3.0.1",
|
||||
@@ -13778,6 +13865,7 @@
|
||||
"integrity": "sha512-/DyMEOrDgLKKIG0fmvtz+4dUX/3Ghozwgm6iPp8KRhvn+eQf9+Q7GWxVNMk3+uCPWfdXYC4ExGBckIXdFEfH1w==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"engines": {
|
||||
"node": ">=10.13.0"
|
||||
}
|
||||
@@ -13795,6 +13883,7 @@
|
||||
"integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"fast-deep-equal": "^3.1.3",
|
||||
"fast-uri": "^3.0.1",
|
||||
|
||||
@@ -11,9 +11,10 @@
|
||||
"core-js": "^3.8.3",
|
||||
"echarts": "^5.6.0",
|
||||
"element-plus": "^2.9.7",
|
||||
"pinia": "^3.0.1",
|
||||
"pinia": "^3.0.3",
|
||||
"qwebchannel": "^6.2.0",
|
||||
"vue": "^3.2.13",
|
||||
"vue-i18n": "^9.14.5",
|
||||
"vue-router": "^4.0.3",
|
||||
"vuex": "^4.0.0"
|
||||
},
|
||||
|
||||
29
src/App.vue
@@ -5,23 +5,28 @@
|
||||
</template>
|
||||
|
||||
<script>
|
||||
|
||||
const debounce = (fn, delay) => {
|
||||
let timer
|
||||
let timer;
|
||||
return (...args) => {
|
||||
if (timer) {
|
||||
clearTimeout(timer)
|
||||
clearTimeout(timer);
|
||||
}
|
||||
timer = setTimeout(() => {
|
||||
fn(...args)
|
||||
}, delay)
|
||||
}
|
||||
}
|
||||
const _ResizeObserver = window.ResizeObserver
|
||||
fn(...args);
|
||||
}, delay);
|
||||
};
|
||||
};
|
||||
const _ResizeObserver = window.ResizeObserver;
|
||||
window.ResizeObserver = class ResizeObserver extends _ResizeObserver {
|
||||
constructor(callback) {
|
||||
callback = debounce(callback, 200)
|
||||
super(callback)
|
||||
callback = debounce(callback, 200);
|
||||
super(callback);
|
||||
}
|
||||
}
|
||||
</script>
|
||||
};
|
||||
</script>
|
||||
|
||||
<!-- <style lang="less">
|
||||
/*每个页面公共css */
|
||||
|
||||
@import "@/static/css/app.less";
|
||||
</style> -->
|
||||
|
||||
@@ -1,17 +1,43 @@
|
||||
import { getAxios, postAxios, downFile } from '@/utils/axios.js'
|
||||
import { ElMessage } from 'element-plus';
|
||||
//租户获取登录id
|
||||
export function rentgetloginID(data) {
|
||||
return getAxios({ url: `/api/tenant/get-id-by-name?name=${data.name}`})
|
||||
}
|
||||
//登录
|
||||
export function login(data) {
|
||||
return postAxios({ url: '/api/user/bigbrother-doLogin', data })
|
||||
}
|
||||
//获取国家
|
||||
export function getCountryinfo(data) {
|
||||
return postAxios({ url: '/api/common/country_info', data })
|
||||
}
|
||||
|
||||
//查询tk账号查询次数
|
||||
export function tkaccountuseinfo(accountName) {
|
||||
return getAxios({ url: `/api/common/accountCount?accountName=${accountName}` })
|
||||
}
|
||||
|
||||
export function tokenVerification() {
|
||||
return getAxios({ url: `/api/common/health` })
|
||||
}
|
||||
|
||||
export function tkhostdata(data) {
|
||||
return postAxios({ url: '/api/big-brother/page', data })
|
||||
}
|
||||
|
||||
|
||||
|
||||
export function apiGetCart() {
|
||||
return getAxios({ url: '/cgi-bin/cart/latest' })
|
||||
}
|
||||
export function login(data) {
|
||||
return postAxios({ url: 'api/account/login', data })
|
||||
}
|
||||
// export function login(data) {
|
||||
// return postAxios({ url: 'api/account/login', data })
|
||||
// }
|
||||
export function cheekalive(data) {
|
||||
return postAxios({ url: 'api/account/cheekalive', data })
|
||||
}
|
||||
export function tkhostdata(data) {
|
||||
return postAxios({ url: 'api/tkinfo/tkhostdata', data })
|
||||
}
|
||||
|
||||
export function dicts(data) {
|
||||
return postAxios({ url: 'api/param/dicts', data })
|
||||
}
|
||||
@@ -25,10 +51,7 @@ export function exporthosts(data) {
|
||||
export function downList(url, data) {
|
||||
return downFile(url, data)
|
||||
}
|
||||
//查询tk账号查询次数
|
||||
export function tkaccountuseinfo(data) {
|
||||
return postAxios({ url: 'api/tkinfo/tkaccountuseinfo', data })
|
||||
}
|
||||
|
||||
//查询员工
|
||||
export function getStaffList(data) {
|
||||
return postAxios({ url: 'api/account/list', data })
|
||||
@@ -41,7 +64,9 @@ export function managerhosts(data) {
|
||||
export function upholdinfo(data) {
|
||||
return postAxios({ url: 'api/tkinfo/upholdinfo', data })
|
||||
}
|
||||
//获取
|
||||
export function getCountryinfo(data) {
|
||||
return postAxios({ url: 'api/tkinfo/countryinfo', data })
|
||||
|
||||
//查看名字
|
||||
export function accountName(str) {
|
||||
return postAxios({ url: 'api/account/accountName?accounts=' + str })
|
||||
}
|
||||
|
||||
|
||||
BIN
src/assets/MiniProgram.png
Normal file
|
After Width: | Height: | Size: 6.9 KiB |
BIN
src/assets/ai.png
Normal file
|
After Width: | Height: | Size: 5.1 KiB |
BIN
src/assets/icon.png
Normal file
|
After Width: | Height: | Size: 32 KiB |
|
Before Width: | Height: | Size: 3.3 KiB After Width: | Height: | Size: 88 KiB |
BIN
src/assets/logo1.png
Normal file
|
After Width: | Height: | Size: 3.3 KiB |
|
Before Width: | Height: | Size: 2.1 MiB After Width: | Height: | Size: 1.3 MiB |
BIN
src/assets/logoBg1.png
Normal file
|
After Width: | Height: | Size: 2.1 MiB |
|
Before Width: | Height: | Size: 4.6 KiB After Width: | Height: | Size: 106 KiB |
BIN
src/assets/logotext1.png
Normal file
|
After Width: | Height: | Size: 4.6 KiB |
BIN
src/assets/logotext12.png
Normal file
|
After Width: | Height: | Size: 21 KiB |
BIN
src/assets/plus.png
Normal file
|
After Width: | Height: | Size: 2.7 KiB |
BIN
src/assets/plus2.png
Normal file
|
After Width: | Height: | Size: 2.7 KiB |
BIN
src/assets/wifi.png
Normal file
|
After Width: | Height: | Size: 6.2 KiB |
@@ -38,6 +38,8 @@ export default {
|
||||
|
||||
this.inputTime = this.time
|
||||
this.getTkhostdetail();
|
||||
console.log(this.time)
|
||||
|
||||
console.log(this.getPrevious7Days(this.inputTime))
|
||||
|
||||
},
|
||||
@@ -93,16 +95,6 @@ export default {
|
||||
res[0][this.getPrevious7Days(this.inputTime)[6]] == null ? 0 : Number(res[0][this.getPrevious7Days(this.inputTime)[6]][this.dataType]),
|
||||
]
|
||||
|
||||
// this.seriesData = {
|
||||
// [this.getPrevious7Days(this.inputTime)[0]]: res[0][this.getPrevious7Days(this.inputTime)[0]] == null ? 0 : res[0][this.getPrevious7Days(this.inputTime)[0]][this.dataType],
|
||||
// [this.getPrevious7Days(this.inputTime)[1]]: res[0][this.getPrevious7Days(this.inputTime)[1]] == null ? 0 : res[0][this.getPrevious7Days(this.inputTime)[1]][this.dataType],
|
||||
// [this.getPrevious7Days(this.inputTime)[2]]: res[0][this.getPrevious7Days(this.inputTime)[2]] == null ? 0 : res[0][this.getPrevious7Days(this.inputTime)[2]][this.dataType],
|
||||
// [this.getPrevious7Days(this.inputTime)[3]]: res[0][this.getPrevious7Days(this.inputTime)[3]] == null ? 0 : res[0][this.getPrevious7Days(this.inputTime)[3]][this.dataType],
|
||||
// [this.getPrevious7Days(this.inputTime)[4]]: res[0][this.getPrevious7Days(this.inputTime)[4]] == null ? 0 : res[0][this.getPrevious7Days(this.inputTime)[4]][this.dataType],
|
||||
// [this.getPrevious7Days(this.inputTime)[5]]: res[0][this.getPrevious7Days(this.inputTime)[5]] == null ? 0 : res[0][this.getPrevious7Days(this.inputTime)[5]][this.dataType],
|
||||
// [this.getPrevious7Days(this.inputTime)[6]]: res[0][this.getPrevious7Days(this.inputTime)[6]] == null ? 0 : res[0][this.getPrevious7Days(this.inputTime)[6]][this.dataType],
|
||||
// }
|
||||
|
||||
this.initChart();
|
||||
this.num++
|
||||
console.log("返回数据", this.seriesData)
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
<template>
|
||||
<div class="sidebar">
|
||||
<div class="logo">
|
||||
<img style="margin-right: 10px;" src="@/assets/logo.png">
|
||||
<!-- <img style="margin-right: 10px;" src="@/assets/logo.png"> -->
|
||||
<img src="@/assets/logotext.png">
|
||||
</div>
|
||||
<ul>
|
||||
<li @click="updateActiveIndex(1)" v-show="userInfo.userType == 3">
|
||||
<li @click="updateActiveIndex(1)">
|
||||
<div>
|
||||
<img v-show="activeIndex == 1" src="@/assets/navAction.png" autoplay loop muted class="background-img">
|
||||
<div style="display: flex;">
|
||||
@@ -45,11 +45,13 @@ import { ref, reactive, onMounted } from 'vue';
|
||||
import { getUser } from '@/utils/storage'
|
||||
import { defineEmits } from 'vue';
|
||||
|
||||
|
||||
|
||||
const userInfo = ref(getUser())
|
||||
|
||||
let activeIndex = ref(userInfo.value.userType == 3 ? 1 : 2);
|
||||
let activeIndex = ref(1);
|
||||
|
||||
const emit = defineEmits(['update:activeIndex']);
|
||||
const emit = defineEmits(['activeIndex']);
|
||||
|
||||
|
||||
const updateActiveIndex = (index) => {
|
||||
@@ -58,23 +60,23 @@ const updateActiveIndex = (index) => {
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
<style scoped lang="less">
|
||||
.sidebar {
|
||||
position: fixed;
|
||||
left: 0;
|
||||
top: 0;
|
||||
height: 900px;
|
||||
width: 280px;
|
||||
background-color: #338F6A;
|
||||
background-color: @bg-color;
|
||||
padding: 20px;
|
||||
box-sizing: border-box;
|
||||
|
||||
.logo {
|
||||
border-bottom: 1px solid #fff;
|
||||
padding-bottom: 29px;
|
||||
padding-top: 20px;
|
||||
|
||||
img:nth-of-type(1) {
|
||||
height: 40px;
|
||||
height: 66px;
|
||||
}
|
||||
|
||||
img:nth-of-type(2) {
|
||||
|
||||
26
src/i18n/index.js
Normal file
@@ -0,0 +1,26 @@
|
||||
import { createI18n } from 'vue-i18n'
|
||||
import zhCn from 'element-plus/dist/locale/zh-cn.mjs'
|
||||
import en from 'element-plus/dist/locale/en.mjs'
|
||||
|
||||
// 导入语言文件
|
||||
import zh from './lang/zh-CN'
|
||||
import enLang from './lang/en-US'
|
||||
|
||||
// 创建 i18n 实例
|
||||
const i18n = createI18n({
|
||||
legacy: false, // 使用 Composition API
|
||||
locale: localStorage.getItem('language') || 'zh-CN', // 默认语言
|
||||
fallbackLocale: 'zh-CN', // 备用语言
|
||||
messages: {
|
||||
'zh-CN': zh,
|
||||
'en-US': enLang
|
||||
}
|
||||
})
|
||||
|
||||
// Element Plus 语言配置
|
||||
export const elementPlusLocale = {
|
||||
'zh-CN': zhCn,
|
||||
'en-US': en
|
||||
}
|
||||
|
||||
export default i18n
|
||||
354
src/i18n/lang/en-US.js
Normal file
@@ -0,0 +1,354 @@
|
||||
export default {
|
||||
common: {
|
||||
networkSettings: 'Network Settings',
|
||||
language: 'Language',
|
||||
simplifiedChinese: 'Simplified Chinese',
|
||||
english: 'English',
|
||||
accountLogin: 'Account Login',
|
||||
tenantName: 'Tenant Name',
|
||||
account: 'Account',
|
||||
password: 'Password',
|
||||
login: 'Login',
|
||||
version: 'Version',
|
||||
expirationtime: 'Expiration Time',
|
||||
},
|
||||
hostsList: {
|
||||
// 顶部筛选
|
||||
filterPrivateUsers: 'Filter Private Users',
|
||||
minCoins: 'Min Coins',
|
||||
maxCoins: 'Max Coins',
|
||||
minLevel: 'Min Level',
|
||||
maxLevel: 'Max Level',
|
||||
specifiedRooms: 'Specified Rooms',
|
||||
specifyRooms: 'Specify Rooms',
|
||||
total: 'Total',
|
||||
valid: 'Valid',
|
||||
reset: 'Reset',
|
||||
start: 'Start',
|
||||
end: 'End',
|
||||
|
||||
// 第二行筛选
|
||||
selectCountry: 'Select Country',
|
||||
bigBrotherId: 'Big Brother ID',
|
||||
search: 'Search',
|
||||
exportExcel: 'Export Excel Data',
|
||||
moreFilters: 'More Filters',
|
||||
openTikTok: 'Open TikTok Login',
|
||||
currentNetwork: 'Current Network',
|
||||
runningTime: 'Running Time',
|
||||
|
||||
// 表格列
|
||||
id: 'Id',
|
||||
hostId: 'Host ID',
|
||||
userId: 'User ID',
|
||||
level: 'Level',
|
||||
fansLevel: 'Fan Club Level',
|
||||
coins: 'Coins',
|
||||
totalGiftCoins: 'Total Gift Coins',
|
||||
region: 'Region',
|
||||
followerCount: 'Followers',
|
||||
followingCount: 'Following',
|
||||
createTime: 'Created Time',
|
||||
|
||||
// 更多筛选弹窗
|
||||
time: 'Time',
|
||||
startTime: 'Start Time',
|
||||
endTime: 'End Time',
|
||||
selectTime: 'Select Query Time',
|
||||
minValue: 'Min Value',
|
||||
maxValue: 'Max Value',
|
||||
enterMinValue: 'Enter Min Value',
|
||||
enterMaxValue: 'Enter Max Value',
|
||||
sort: 'Sort',
|
||||
sortType: 'Sort Type',
|
||||
sortOrder: 'Ascending/Descending',
|
||||
pleaseSelect: 'Please Select',
|
||||
ascending: 'Ascending',
|
||||
descending: 'Descending',
|
||||
confirm: 'Confirm',
|
||||
cancel: 'Cancel',
|
||||
|
||||
// 指定直播间弹窗
|
||||
cancelSpecify: 'Cancel Specify Rooms',
|
||||
specifyReset: 'Reset',
|
||||
specifyConfirm: 'Confirm',
|
||||
specifyStart: 'Start',
|
||||
enterRoomIds: 'Enter room IDs, separate multiple IDs with Enter key',
|
||||
enterRoomId: 'Please enter room ID',
|
||||
|
||||
// 网络问题弹窗
|
||||
networkFailed:
|
||||
'Network connection failed, unable to access the network. Please check network settings.',
|
||||
|
||||
// 复制提示
|
||||
noContentToCopy: 'No content to copy',
|
||||
copySuccess: 'Copied successfully',
|
||||
copyFailed: 'Copy failed',
|
||||
|
||||
// 任务状态 loading
|
||||
stopping: 'Stopping...',
|
||||
starting: 'Starting...',
|
||||
|
||||
// 获取国家失败弹窗
|
||||
pleaseEnterCountryName: 'Please enter the country name in Chinese',
|
||||
getCountryFailed: 'Failed to get country',
|
||||
},
|
||||
|
||||
// ==== 新增:国家名称国际化 ====
|
||||
countries: {
|
||||
AD: "Andorra",
|
||||
AE: "United Arab Emirates",
|
||||
AF: "Afghanistan",
|
||||
AG: "Antigua and Barbuda",
|
||||
AI: "Anguilla",
|
||||
AL: "Albania",
|
||||
AM: "Armenia",
|
||||
AO: "Angola",
|
||||
AQ: "Antarctica",
|
||||
AR: "Argentina",
|
||||
AS: "American Samoa",
|
||||
AT: "Austria",
|
||||
AU: "Australia",
|
||||
AU1: "Australia",
|
||||
AW: "Aruba",
|
||||
AX: "Åland Islands",
|
||||
AZ: "Azerbaijan",
|
||||
BA: "Bosnia and Herzegovina",
|
||||
BB: "Barbados",
|
||||
BD: "Bangladesh",
|
||||
BE: "Belgium",
|
||||
BF: "Burkina Faso",
|
||||
BG: "Bulgaria",
|
||||
BH: "Bahrain",
|
||||
BI: "Burundi",
|
||||
BJ: "Benin",
|
||||
BL: "Saint Barthélemy",
|
||||
BM: "Bermuda",
|
||||
BN: "Brunei Darussalam",
|
||||
BO: "Bolivia",
|
||||
BQ: "Bonaire, Sint Eustatius and Saba",
|
||||
BR: "Brazil",
|
||||
BS: "Bahamas",
|
||||
BT: "Bhutan",
|
||||
BV: "Bouvet Island",
|
||||
BW: "Botswana",
|
||||
BY: "Belarus",
|
||||
BZ: "Belize",
|
||||
CA: "Canada",
|
||||
CA1: "Canada",
|
||||
CC: "Cocos (Keeling) Islands",
|
||||
CD: "Democratic Republic of the Congo",
|
||||
CF: "Central African Republic",
|
||||
CG: "Republic of the Congo",
|
||||
CH: "Switzerland",
|
||||
CI: "Côte d'Ivoire",
|
||||
CK: "Cook Islands",
|
||||
CL: "Chile",
|
||||
CM: "Cameroon",
|
||||
CN: "China",
|
||||
CO: "Colombia",
|
||||
CR: "Costa Rica",
|
||||
CU: "Cuba",
|
||||
CV: "Cape Verde",
|
||||
CW: "Curaçao",
|
||||
CX: "Christmas Island",
|
||||
CY: "Cyprus",
|
||||
CZ: "Czech Republic",
|
||||
DE: "Germany",
|
||||
DG: "Diego Garcia",
|
||||
DJ: "Djibouti",
|
||||
DK: "Denmark",
|
||||
DM: "Dominica",
|
||||
DO: "Dominican Republic",
|
||||
DZ: "Algeria",
|
||||
EC: "Ecuador",
|
||||
EE: "Estonia",
|
||||
EG: "Egypt",
|
||||
EH: "Western Sahara",
|
||||
ER: "Eritrea",
|
||||
ES: "Spain",
|
||||
ET: "Ethiopia",
|
||||
FI: "Finland",
|
||||
FJ: "Fiji",
|
||||
FK: "Falkland Islands",
|
||||
FM: "Micronesia",
|
||||
FO: "Faroe Islands",
|
||||
FR: "France",
|
||||
GA: "Gabon",
|
||||
GB: "United Kingdom",
|
||||
GD: "Grenada",
|
||||
GE: "Georgia",
|
||||
GF: "French Guiana",
|
||||
GG: "Guernsey",
|
||||
GH: "Ghana",
|
||||
GI: "Gibraltar",
|
||||
GL: "Greenland",
|
||||
GM: "Gambia",
|
||||
GN: "Guinea",
|
||||
GP: "Guadeloupe",
|
||||
GQ: "Equatorial Guinea",
|
||||
GR: "Greece",
|
||||
GS: "South Georgia and the South Sandwich Islands",
|
||||
GT: "Guatemala",
|
||||
GU: "Guam",
|
||||
GW: "Guinea-Bissau",
|
||||
GY: "Guyana",
|
||||
HK: "Hong Kong SAR China",
|
||||
HM: "Heard Island and McDonald Islands",
|
||||
HN: "Honduras",
|
||||
HR: "Croatia",
|
||||
HT: "Haiti",
|
||||
HU: "Hungary",
|
||||
ID: "Indonesia",
|
||||
IE: "Ireland",
|
||||
IL: "Israel",
|
||||
IM: "Isle of Man",
|
||||
IN: "India",
|
||||
IO: "British Indian Ocean Territory",
|
||||
IQ: "Iraq",
|
||||
IR: "Iran",
|
||||
IS: "Iceland",
|
||||
IT: "Italy",
|
||||
JE: "Jersey",
|
||||
JM: "Jamaica",
|
||||
JO: "Jordan",
|
||||
JP: "Japan",
|
||||
JP1: "Japan",
|
||||
KE: "Kenya",
|
||||
KG: "Kyrgyzstan",
|
||||
KH: "Cambodia",
|
||||
KI: "Kiribati",
|
||||
KM: "Comoros",
|
||||
KN: "Saint Kitts and Nevis",
|
||||
KP: "North Korea",
|
||||
KR: "South Korea",
|
||||
KR1: "South Korea",
|
||||
KR1_UXWAUDIT: "South Korea",
|
||||
KW: "Kuwait",
|
||||
KY: "Cayman Islands",
|
||||
KZ: "Kazakhstan",
|
||||
LA: "Laos",
|
||||
LB: "Lebanon",
|
||||
LC: "Saint Lucia",
|
||||
LI: "Liechtenstein",
|
||||
LK: "Sri Lanka",
|
||||
LR: "Liberia",
|
||||
LS: "Lesotho",
|
||||
LT: "Lithuania",
|
||||
LU: "Luxembourg",
|
||||
LV: "Latvia",
|
||||
LY: "Libya",
|
||||
MA: "Morocco",
|
||||
MC: "Monaco",
|
||||
MD: "Moldova",
|
||||
ME: "Montenegro",
|
||||
MF: "Saint Martin",
|
||||
MG: "Madagascar",
|
||||
MH: "Marshall Islands",
|
||||
MK: "North Macedonia",
|
||||
ML: "Mali",
|
||||
MM: "Myanmar",
|
||||
MN: "Mongolia",
|
||||
MO: "Macao SAR China",
|
||||
MP: "Northern Mariana Islands",
|
||||
MQ: "Martinique",
|
||||
MR: "Mauritania",
|
||||
MS: "Montserrat",
|
||||
MT: "Malta",
|
||||
MU: "Mauritius",
|
||||
MV: "Maldives",
|
||||
MW: "Malawi",
|
||||
MX: "Mexico",
|
||||
MY: "Malaysia",
|
||||
MZ: "Mozambique",
|
||||
NA: "Namibia",
|
||||
NC: "New Caledonia",
|
||||
NE: "Niger",
|
||||
NF: "Norfolk Island",
|
||||
NG: "Nigeria",
|
||||
NI: "Nicaragua",
|
||||
NL: "Netherlands",
|
||||
NO: "Norway",
|
||||
NP: "Nepal",
|
||||
NR: "Nauru",
|
||||
NU: "Niue",
|
||||
NZ: "New Zealand",
|
||||
OM: "Oman",
|
||||
PA: "Panama",
|
||||
PE: "Peru",
|
||||
PF: "French Polynesia",
|
||||
PG: "Papua New Guinea",
|
||||
PH: "Philippines",
|
||||
PK: "Pakistan",
|
||||
PL: "Poland",
|
||||
PM: "Saint Pierre and Miquelon",
|
||||
PN: "Pitcairn Islands",
|
||||
PR: "Puerto Rico",
|
||||
PS: "Palestine",
|
||||
PT: "Portugal",
|
||||
PW: "Palau",
|
||||
PY: "Paraguay",
|
||||
QA: "Qatar",
|
||||
RE: "Réunion",
|
||||
RO: "Romania",
|
||||
RS: "Serbia",
|
||||
RU: "Russia",
|
||||
RW: "Rwanda",
|
||||
SA: "Saudi Arabia",
|
||||
SB: "Solomon Islands",
|
||||
SC: "Seychelles",
|
||||
SD: "Sudan",
|
||||
SE: "Sweden",
|
||||
SG: "Singapore",
|
||||
SI: "Slovenia",
|
||||
SJ: "Svalbard and Jan Mayen",
|
||||
SK: "Slovakia",
|
||||
SL: "Sierra Leone",
|
||||
SM: "San Marino",
|
||||
SN: "Senegal",
|
||||
SO: "Somalia",
|
||||
SR: "Suriname",
|
||||
SS: "South Sudan",
|
||||
ST: "Sao Tome and Principe",
|
||||
SV: "El Salvador",
|
||||
SX: "Sint Maarten",
|
||||
SY: "Syria",
|
||||
SZ: "Eswatini",
|
||||
TC: "Turks and Caicos Islands",
|
||||
TD: "Chad",
|
||||
TF: "French Southern Territories",
|
||||
TG: "Togo",
|
||||
TH: "Thailand",
|
||||
TJ: "Tajikistan",
|
||||
TK: "Tokelau",
|
||||
TL: "Timor-Leste",
|
||||
TM: "Turkmenistan",
|
||||
TN: "Tunisia",
|
||||
TO: "Tonga",
|
||||
TR: "Turkey",
|
||||
TT: "Trinidad and Tobago",
|
||||
TV: "Tuvalu",
|
||||
TW: "Taiwan",
|
||||
TZ: "Tanzania",
|
||||
UA: "Ukraine",
|
||||
UG: "Uganda",
|
||||
UM: "United States Minor Outlying Islands",
|
||||
US: "United States",
|
||||
UY: "Uruguay",
|
||||
UZ: "Uzbekistan",
|
||||
VA: "Vatican City",
|
||||
VC: "Saint Vincent and the Grenadines",
|
||||
VE: "Venezuela",
|
||||
VG: "British Virgin Islands",
|
||||
VI: "U.S. Virgin Islands",
|
||||
VN: "Vietnam",
|
||||
VN1: "Vietnam",
|
||||
VU: "Vanuatu",
|
||||
WS: "Samoa",
|
||||
YE: "Yemen",
|
||||
YT: "Mayotte",
|
||||
ZA: "South Africa",
|
||||
ZM: "Zambia",
|
||||
ZW: "Zimbabwe"
|
||||
}
|
||||
}
|
||||
347
src/i18n/lang/zh-CN.js
Normal file
@@ -0,0 +1,347 @@
|
||||
export default {
|
||||
common: {
|
||||
networkSettings: '网络设置',
|
||||
language: '语言',
|
||||
simplifiedChinese: '简体中文',
|
||||
english: 'English',
|
||||
accountLogin: '账号登录',
|
||||
tenantName: '租户名称',
|
||||
account: '账号',
|
||||
password: '密码',
|
||||
login: '登录',
|
||||
version: '版本号',
|
||||
expirationtime: '过期时间',
|
||||
},
|
||||
hostsList: {
|
||||
filterPrivateUsers: '过滤隐私用户',
|
||||
minCoins: '最小金币',
|
||||
maxCoins: '最大金币',
|
||||
minLevel: '最小等级',
|
||||
maxLevel: '最大等级',
|
||||
specifiedRooms: '已指定直播间',
|
||||
specifyRooms: '指定直播间',
|
||||
total: '总数',
|
||||
valid: '有效数',
|
||||
reset: '重置',
|
||||
start: '开始',
|
||||
end: '结束',
|
||||
selectCountry: '选择国家',
|
||||
bigBrotherId: '大哥id',
|
||||
search: '查询',
|
||||
exportExcel: '导出Excel数据',
|
||||
moreFilters: '更多筛选',
|
||||
openTikTok: '打开 TikTok 登录',
|
||||
currentNetwork: '当前网络',
|
||||
runningTime: '运行时间',
|
||||
id: 'Id',
|
||||
hostId: '所在直播间主播id',
|
||||
time: '时间',
|
||||
startTime: '开始时间',
|
||||
endTime: '结束时间',
|
||||
selectTime: '选择查询时间',
|
||||
minValue: '最小值',
|
||||
maxValue: '最大值',
|
||||
enterMinValue: '请输入最小值',
|
||||
enterMaxValue: '请输入最大值',
|
||||
sort: '排序',
|
||||
sortType: '排序类型',
|
||||
sortOrder: '升序/降序',
|
||||
pleaseSelect: '请选择',
|
||||
ascending: '升序',
|
||||
descending: '降序',
|
||||
confirm: '确认',
|
||||
cancel: '取消',
|
||||
cancelSpecify: '取消指定直播间',
|
||||
specifyReset: '重置',
|
||||
specifyConfirm: '确认',
|
||||
specifyStart: '开始',
|
||||
networkFailed: '网络连接失败,无法访问网络,请查看网络设置。',
|
||||
enterRoomIds: '请输入直播间id,多个id用回车键隔开',
|
||||
|
||||
// ==== 新增:表格列、排序使用 ====
|
||||
userId: '用户id',
|
||||
level: '等级',
|
||||
fansLevel: '粉丝团等级',
|
||||
coins: '打赏的金币',
|
||||
totalGiftCoins: '打赏金币总和',
|
||||
region: '地区',
|
||||
followerCount: '粉丝数',
|
||||
followingCount: '关注数',
|
||||
createTime: '创建时间',
|
||||
|
||||
// ==== 新增:复制提示 ====
|
||||
noContentToCopy: '无内容可复制',
|
||||
copySuccess: '复制成功',
|
||||
copyFailed: '复制失败',
|
||||
|
||||
// ==== 新增:获取国家失败弹窗 ====
|
||||
pleaseEnterCountryName: '请输入要获取的国家',
|
||||
getCountryFailed: '获取国家失败',
|
||||
|
||||
// ==== 新增:loading 提示 ====
|
||||
stopping: '正在停止...',
|
||||
starting: '正在启动...',
|
||||
|
||||
// ==== 新增:单个直播间id校验提示 ====
|
||||
enterRoomId: '请输入直播间id',
|
||||
},
|
||||
|
||||
// ==== 新增:国家名称国际化 ====
|
||||
countries: {
|
||||
AD: "安道尔",
|
||||
AE: "阿拉伯联合酋长国",
|
||||
AF: "阿富汗",
|
||||
AG: "安提瓜和巴布达",
|
||||
AI: "安圭拉",
|
||||
AL: "阿尔巴尼亚",
|
||||
AM: "亚美尼亚",
|
||||
AO: "安哥拉",
|
||||
AQ: "南极洲",
|
||||
AR: "阿根廷",
|
||||
AS: "美属萨摩亚",
|
||||
AT: "奥地利",
|
||||
AU: "澳大利亚",
|
||||
AU1: "澳大利亚",
|
||||
AW: "阿鲁巴",
|
||||
AX: "奥兰群岛",
|
||||
AZ: "阿塞拜疆",
|
||||
BA: "波斯尼亚和黑塞哥维那",
|
||||
BB: "巴巴多斯",
|
||||
BD: "孟加拉国",
|
||||
BE: "比利时",
|
||||
BF: "布基纳法索",
|
||||
BG: "保加利亚",
|
||||
BH: "巴林",
|
||||
BI: "布隆迪",
|
||||
BJ: "贝宁",
|
||||
BL: "圣巴泰勒米",
|
||||
BM: "百慕大群岛",
|
||||
BN: "文莱达鲁萨兰国",
|
||||
BO: "玻利维亚",
|
||||
BQ: "博奈尔、圣尤斯特歇斯和萨巴",
|
||||
BR: "巴西",
|
||||
BS: "巴哈马",
|
||||
BT: "不丹",
|
||||
BV: "布韦岛",
|
||||
BW: "博茨瓦纳",
|
||||
BY: "白俄罗斯",
|
||||
BZ: "伯利兹",
|
||||
CA: "加拿大",
|
||||
CA1: "加拿大",
|
||||
CC: "科科斯(基林)群岛",
|
||||
CD: "刚果民主共和国",
|
||||
CF: "中非共和国",
|
||||
CG: "刚果共和国",
|
||||
CH: "瑞士",
|
||||
CI: "科特迪瓦",
|
||||
CK: "库克群岛",
|
||||
CL: "智利",
|
||||
CM: "喀麦隆",
|
||||
CN: "中国",
|
||||
CO: "哥伦比亚",
|
||||
CR: "哥斯达黎加",
|
||||
CU: "古巴",
|
||||
CV: "佛得角",
|
||||
CW: "库拉索",
|
||||
CX: "圣诞岛",
|
||||
CY: "塞浦路斯",
|
||||
CZ: "捷克共和国",
|
||||
DE: "德国",
|
||||
DG: "迪戈加西亚岛",
|
||||
DJ: "吉布提",
|
||||
DK: "丹麦",
|
||||
DM: "多米尼克",
|
||||
DO: "多米尼加共和国",
|
||||
DZ: "阿尔及利亚",
|
||||
EC: "厄瓜多尔",
|
||||
EE: "爱沙尼亚",
|
||||
EG: "埃及",
|
||||
EH: "西撒哈拉",
|
||||
ER: "厄立特里亚",
|
||||
ES: "西班牙",
|
||||
ET: "埃塞俄比亚",
|
||||
FI: "芬兰",
|
||||
FJ: "斐济",
|
||||
FK: "福克兰群岛",
|
||||
FM: "密克罗尼西亚",
|
||||
FO: "法罗群岛",
|
||||
FR: "法国",
|
||||
GA: "加蓬",
|
||||
GB: "英国",
|
||||
GD: "格林纳达",
|
||||
GE: "格鲁吉亚",
|
||||
GF: "法属圭亚那",
|
||||
GG: "根西岛",
|
||||
GH: "加纳",
|
||||
GI: "直布罗陀",
|
||||
GL: "格陵兰",
|
||||
GM: "冈比亚",
|
||||
GN: "几内亚",
|
||||
GP: "瓜德罗普",
|
||||
GQ: "赤道几内亚",
|
||||
GR: "希腊",
|
||||
GS: "南乔治亚和南桑德威奇群岛",
|
||||
GT: "危地马拉",
|
||||
GU: "关岛",
|
||||
GW: "几内亚比绍",
|
||||
GY: "圭亚那",
|
||||
HK: "中国香港特别行政区",
|
||||
HM: "赫德岛和麦克唐纳群岛",
|
||||
HN: "洪都拉斯",
|
||||
HR: "克罗地亚",
|
||||
HT: "海地",
|
||||
HU: "匈牙利",
|
||||
ID: "印度尼西亚",
|
||||
IE: "爱尔兰",
|
||||
IL: "以色列",
|
||||
IM: "马恩岛",
|
||||
IN: "印度",
|
||||
IO: "英属印度洋领地",
|
||||
IQ: "伊拉克",
|
||||
IR: "伊朗",
|
||||
IS: "冰岛",
|
||||
IT: "意大利",
|
||||
JE: "泽西岛",
|
||||
JM: "牙买加",
|
||||
JO: "约旦",
|
||||
JP: "日本",
|
||||
JP1: "日本",
|
||||
KE: "肯尼亚",
|
||||
KG: "吉尔吉斯斯坦",
|
||||
KH: "柬埔寨",
|
||||
KI: "基里巴斯",
|
||||
KM: "科摩罗",
|
||||
KN: "圣基茨和尼维斯",
|
||||
KP: "朝鲜",
|
||||
KR: "韩国",
|
||||
KR1: "韩国",
|
||||
KR1_UXWAUDIT: "韩国",
|
||||
KW: "科威特",
|
||||
KY: "开曼群岛",
|
||||
KZ: "哈萨克斯坦",
|
||||
LA: "老挝",
|
||||
LB: "黎巴嫩",
|
||||
LC: "圣卢西亚",
|
||||
LI: "列支敦士登",
|
||||
LK: "斯里兰卡",
|
||||
LR: "利比里亚",
|
||||
LS: "莱索托",
|
||||
LT: "立陶宛",
|
||||
LU: "卢森堡",
|
||||
LV: "拉脱维亚",
|
||||
LY: "利比亚",
|
||||
MA: "摩洛哥",
|
||||
MC: "摩纳哥",
|
||||
MD: "摩尔多瓦",
|
||||
ME: "黑山",
|
||||
MF: "圣马丁",
|
||||
MG: "马达加斯加",
|
||||
MH: "马绍尔群岛",
|
||||
MK: "北马其顿",
|
||||
ML: "马里",
|
||||
MM: "缅甸",
|
||||
MN: "蒙古",
|
||||
MO: "中国澳门特别行政区",
|
||||
MP: "北马里亚纳群岛",
|
||||
MQ: "马提尼克",
|
||||
MR: "毛里塔尼亚",
|
||||
MS: "蒙特塞拉特",
|
||||
MT: "马耳他",
|
||||
MU: "毛里求斯",
|
||||
MV: "马尔代夫",
|
||||
MW: "马拉维",
|
||||
MX: "墨西哥",
|
||||
MY: "马来西亚",
|
||||
MZ: "莫桑比克",
|
||||
NA: "纳米比亚",
|
||||
NC: "新喀里多尼亚",
|
||||
NE: "尼日尔",
|
||||
NF: "诺福克岛",
|
||||
NG: "尼日利亚",
|
||||
NI: "尼加拉瓜",
|
||||
NL: "荷兰",
|
||||
NO: "挪威",
|
||||
NP: "尼泊尔",
|
||||
NR: "瑙鲁",
|
||||
NU: "纽埃",
|
||||
NZ: "新西兰",
|
||||
OM: "阿曼",
|
||||
PA: "巴拿马",
|
||||
PE: "秘鲁",
|
||||
PF: "法属玻利尼西亚",
|
||||
PG: "巴布亚新几内亚",
|
||||
PH: "菲律宾",
|
||||
PK: "巴基斯坦",
|
||||
PL: "波兰",
|
||||
PM: "圣皮埃尔和密克隆群岛",
|
||||
PN: "皮特凯恩群岛",
|
||||
PR: "波多黎各",
|
||||
PS: "巴勒斯坦",
|
||||
PT: "葡萄牙",
|
||||
PW: "帕劳",
|
||||
PY: "巴拉圭",
|
||||
QA: "卡塔尔",
|
||||
RE: "留尼汪",
|
||||
RO: "罗马尼亚",
|
||||
RS: "塞尔维亚",
|
||||
RU: "俄罗斯",
|
||||
RW: "卢旺达",
|
||||
SA: "沙特阿拉伯",
|
||||
SB: "索罗门群岛",
|
||||
SC: "塞舌尔",
|
||||
SD: "苏丹",
|
||||
SE: "瑞典",
|
||||
SG: "新加坡",
|
||||
SI: "斯洛文尼亚",
|
||||
SJ: "斯瓦尔巴和扬马延",
|
||||
SK: "斯洛伐克",
|
||||
SL: "塞拉利昂",
|
||||
SM: "圣马利诺",
|
||||
SN: "塞内加尔",
|
||||
SO: "索马里",
|
||||
SR: "苏里南",
|
||||
SS: "南苏丹",
|
||||
ST: "圣多美和普林西比",
|
||||
SV: "萨尔瓦多",
|
||||
SX: "荷属圣马丁",
|
||||
SY: "叙利亚",
|
||||
SZ: "斯威士兰",
|
||||
TC: "特克斯和凯科斯群岛",
|
||||
TD: "乍得",
|
||||
TF: "法属南部领地",
|
||||
TG: "多哥",
|
||||
TH: "泰国",
|
||||
TJ: "塔吉克斯坦",
|
||||
TK: "托克劳群岛",
|
||||
TL: "东帝汶",
|
||||
TM: "土库曼斯坦",
|
||||
TN: "突尼斯",
|
||||
TO: "汤加",
|
||||
TR: "土耳其",
|
||||
TT: "特立尼达和多巴哥",
|
||||
TV: "图瓦卢",
|
||||
TW: "台湾",
|
||||
TZ: "坦桑尼亚",
|
||||
UA: "乌克兰",
|
||||
UG: "乌干达",
|
||||
UM: "美国本土外小岛屿",
|
||||
US: "美国",
|
||||
UY: "乌拉圭",
|
||||
UZ: "乌兹别克斯坦",
|
||||
VA: "梵蒂冈",
|
||||
VC: "圣文森特",
|
||||
VE: "委内瑞拉",
|
||||
VG: "英属维尔京群岛",
|
||||
VI: "美属维尔京群岛",
|
||||
VN: "越南",
|
||||
VN1: "越南",
|
||||
VU: "瓦努阿图",
|
||||
WS: "萨摩亚",
|
||||
YE: "也门",
|
||||
YT: "马约特岛",
|
||||
ZA: "南非",
|
||||
ZM: "赞比亚",
|
||||
ZW: "津巴布韦"
|
||||
}
|
||||
|
||||
}
|
||||
17
src/main.js
@@ -5,14 +5,19 @@ import store from './store'
|
||||
import { createPinia } from 'pinia';
|
||||
import ElementPlus from 'element-plus'
|
||||
import 'element-plus/dist/index.css'
|
||||
|
||||
// createApp(App).use(store).use(router).mount('#app')
|
||||
|
||||
import i18n, { elementPlusLocale } from './i18n'
|
||||
|
||||
const app = createApp(App);
|
||||
app.use(ElementPlus) // 注册 ElementPlus
|
||||
|
||||
// 获取当前语言
|
||||
const currentLocale = localStorage.getItem('language') || 'zh-CN'
|
||||
|
||||
app.use(ElementPlus, {
|
||||
locale: elementPlusLocale[currentLocale] // 动态配置Element Plus语言
|
||||
});
|
||||
|
||||
app.use(i18n); // 注册 i18n
|
||||
app.use(createPinia()); // 注册 Pinia
|
||||
app.use(store); // 注册 store
|
||||
app.use(router); // 注册 router
|
||||
app.mount('#app');
|
||||
|
||||
app.mount('#app');
|
||||
@@ -19,11 +19,12 @@ const routes = [
|
||||
name: 'hostsList',
|
||||
component: () => import(/* webpackChunkName: "hostsList" */ '../views/hosts/hostsList.vue')
|
||||
},
|
||||
{
|
||||
path: 'workBenches',
|
||||
name: 'workBenches',
|
||||
component: () => import(/* webpackChunkName: "hostsList" */ '../views/hosts/workbenches.vue')
|
||||
},]
|
||||
// {
|
||||
// path: 'workBenches',
|
||||
// name: 'workBenches',
|
||||
// component: () => import(/* webpackChunkName: "hostsList" */ '../views/hosts/workbenches.vue')
|
||||
// },
|
||||
]
|
||||
}
|
||||
]
|
||||
const router = createRouter({
|
||||
|
||||
4
src/static/css/app.less
Normal file
@@ -0,0 +1,4 @@
|
||||
@bg-color: #022b4e; // 主色
|
||||
@bg-color-light: #022b4eaf; // 浅主色
|
||||
@bg-color-light-light: #022b4e1c; // 浅浅主色
|
||||
@btn-bg-color: #045dac; // 黄色按钮主色
|
||||
@@ -9,4 +9,29 @@ export const noticeStore = defineStore('noticeNum', {
|
||||
this.data.num++;
|
||||
},
|
||||
},
|
||||
});
|
||||
});
|
||||
export const tokenStore = defineStore('token', {
|
||||
state: () => {
|
||||
return { token: '' }
|
||||
},
|
||||
// 也可以这样定义
|
||||
// state: () => ({ count: 0 })
|
||||
actions: {
|
||||
setToken(token){
|
||||
this.token = token
|
||||
}
|
||||
},
|
||||
})
|
||||
|
||||
export const UserStore = defineStore('User', {
|
||||
state: () => {
|
||||
return { user: {} }
|
||||
},
|
||||
// 也可以这样定义
|
||||
// state: () => ({ count: 0 })
|
||||
actions: {
|
||||
setUser(user){
|
||||
this.user = user
|
||||
}
|
||||
},
|
||||
})
|
||||
@@ -4,33 +4,53 @@
|
||||
*/
|
||||
import axios from 'axios'
|
||||
import { getToken, getUser } from '@/utils/storage'
|
||||
import { useRouter } from 'vue-router';
|
||||
import { ElMessage } from 'element-plus';
|
||||
import router from '@/router'
|
||||
|
||||
import { ElMessage } from 'element-plus';
|
||||
import { usePythonBridge, } from '@/utils/pythonBridge'
|
||||
import { ref } from 'vue';
|
||||
import { defineStore } from 'pinia'
|
||||
import { tokenStore,UserStore } from '@/stores/notice'
|
||||
|
||||
|
||||
|
||||
|
||||
const { stopScript } = usePythonBridge();
|
||||
|
||||
const router = useRouter();
|
||||
|
||||
// 请求地址前缀
|
||||
let baseURL = ''
|
||||
if (process.env.NODE_ENV === 'development') {
|
||||
// 生产环境
|
||||
baseURL = "http://120.26.251.180:8085/"
|
||||
// baseURL = "http://192.168.0.115:8085/"
|
||||
baseURL = "https://crawlclient.api.yolozs.com"
|
||||
// baseURL = "http://47.79.98.113:8101"
|
||||
// baseURL = "http://192.168.0.103:8085/"
|
||||
// baseURL = "http://192.168.1.144:8101"
|
||||
} else {
|
||||
// 测试环境
|
||||
// baseURL = "http://120.26.251.180:8085/"
|
||||
// 开发环境
|
||||
baseURL = "http://120.26.251.180:8085/"
|
||||
baseURL = "https://crawlclient.api.yolozs.com"
|
||||
// baseURL = "http://47.79.98.113:8101"
|
||||
// baseURL = "http://192.168.1.144:8101"
|
||||
// baseURL = "http://api.tkpage.vvtiktok.cn"
|
||||
}
|
||||
|
||||
// 请求拦截器
|
||||
axios.interceptors.request.use((config) => {
|
||||
// if (getToken()) {
|
||||
// config.headers['token'] = getToken();
|
||||
// }
|
||||
|
||||
const tokenCache = tokenStore()
|
||||
console.log("config", config)
|
||||
const url = sliceUrl(config.url)
|
||||
console.log("url", url)
|
||||
// 请求超时时间 - 毫秒
|
||||
config.timeout = 60000
|
||||
config.baseURL = baseURL
|
||||
// 自定义Content-type
|
||||
config.headers['Content-type'] = 'application/json'
|
||||
if (!(config.url == 'bigbrother-doLogin' || config.url == 'get-id-by-name')) {
|
||||
config.headers['vvtoken'] = tokenCache.token;
|
||||
}
|
||||
|
||||
return config;
|
||||
}, (error) => {
|
||||
return Promise.reject(error)
|
||||
@@ -38,7 +58,19 @@ axios.interceptors.request.use((config) => {
|
||||
|
||||
// 响应拦截器
|
||||
axios.interceptors.response.use((response) => {
|
||||
return response
|
||||
console.log("response", response.data)
|
||||
if (response.data.code == 0) {
|
||||
console.log("response", response.data.data)
|
||||
return response.data.data
|
||||
} else if (response.data.code == 40400) {
|
||||
router.push('/')
|
||||
ElMessage.error(response.data.code + '' + response.data.message);
|
||||
}else{
|
||||
ElMessage.error(response.data.code + '' + response.data.message);
|
||||
}
|
||||
|
||||
|
||||
|
||||
}, (error) => {
|
||||
// 可添加请求失败后的处理逻辑
|
||||
return Promise.reject(error)
|
||||
@@ -54,10 +86,9 @@ export function getAxios({ url, params }) {
|
||||
params
|
||||
// 请求成功,将返回的数据传递给resolve函数
|
||||
}).then(res => {
|
||||
resolve(res.data)
|
||||
resolve(res)
|
||||
// 请求失败,将错误信息传递给reject函数
|
||||
}).catch(err => {
|
||||
console.log(err)
|
||||
reject(err)
|
||||
})
|
||||
})
|
||||
@@ -65,13 +96,6 @@ export function getAxios({ url, params }) {
|
||||
|
||||
// axios的post请求
|
||||
export function postAxios({ url, data }) {
|
||||
if (url != 'api/account/login') {
|
||||
|
||||
throttledCheekalive();
|
||||
|
||||
}
|
||||
|
||||
|
||||
return new Promise((resolve, reject) => {
|
||||
axios.post(
|
||||
url,
|
||||
@@ -82,20 +106,9 @@ export function postAxios({ url, data }) {
|
||||
}
|
||||
}
|
||||
).then(res => {
|
||||
resolve(res.data)
|
||||
resolve(res)
|
||||
}).catch(err => {
|
||||
if (err.message == "Network Error") {
|
||||
// alert("网络错误,请检查网络连接")
|
||||
ElMessage.error('网络连接错误');
|
||||
reject('网络连接错误')
|
||||
|
||||
} else {
|
||||
ElMessage.error(err.message);
|
||||
reject(err.message)
|
||||
|
||||
}
|
||||
// console.log(err)
|
||||
// reject(err)
|
||||
reject(err)
|
||||
})
|
||||
})
|
||||
}
|
||||
@@ -132,9 +145,11 @@ export const downFile = async (urlstr, data) => {
|
||||
}
|
||||
//请求前验证
|
||||
function cheekalive() {
|
||||
const userCache = UserStore()
|
||||
const tokenCache = tokenStore()
|
||||
axios.post('api/account/cheekalive', {
|
||||
userId: getUser().userId,
|
||||
currcode: getToken(),
|
||||
userId: userCache.user.id,
|
||||
currcode: tokenCache.token,
|
||||
},
|
||||
{
|
||||
headers: {
|
||||
@@ -146,6 +161,7 @@ function cheekalive() {
|
||||
if (res.data) {
|
||||
|
||||
} else {
|
||||
stopScript();
|
||||
alert("账号在其他地方登录!")
|
||||
window.location.href = '/';
|
||||
}
|
||||
@@ -167,6 +183,18 @@ function throttle(func, limit) {
|
||||
}
|
||||
}
|
||||
|
||||
const throttledCheekalive = throttle(cheekalive, 5000);
|
||||
function sliceUrl(url) {
|
||||
const lastSlash = url.lastIndexOf('/');
|
||||
const questionMark = url.indexOf('?');
|
||||
if (questionMark == -1) {
|
||||
const result = url.slice(lastSlash + 1, url.length);
|
||||
return result;
|
||||
} else {
|
||||
const result = url.slice(lastSlash + 1, questionMark);
|
||||
return result;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
export default axios
|
||||
@@ -1,261 +1,270 @@
|
||||
// country-utils.js
|
||||
import i18n from '../i18n'
|
||||
|
||||
// 国家代码枚举(只包含代码,不包含名称)
|
||||
export const CountryCode = {
|
||||
AD: "安道尔",
|
||||
AE: "阿拉伯联合酋长国",
|
||||
AF: "阿富汗",
|
||||
AG: "安提瓜和巴布达",
|
||||
AI: "安圭拉",
|
||||
AL: "阿尔巴尼亚",
|
||||
AM: "亚美尼亚",
|
||||
AO: "安哥拉",
|
||||
AQ: "南极洲",
|
||||
AR: "阿根廷",
|
||||
AS: "美属萨摩亚",
|
||||
AT: "奥地利",
|
||||
AU: "澳大利亚",
|
||||
AU1: "澳大利亚",
|
||||
AW: "阿鲁巴",
|
||||
AX: "奥兰群岛",
|
||||
AZ: "阿塞拜疆",
|
||||
BA: "波斯尼亚和黑塞哥维那",
|
||||
BB: "巴巴多斯",
|
||||
BD: "孟加拉国",
|
||||
BE: "比利时",
|
||||
BF: "布基纳法索",
|
||||
BG: "保加利亚",
|
||||
BH: "巴林",
|
||||
BI: "布隆迪",
|
||||
BJ: "贝宁",
|
||||
BL: "圣巴泰勒米",
|
||||
BM: "百慕大群岛",
|
||||
BN: "文莱达鲁萨兰国",
|
||||
BO: "玻利维亚",
|
||||
BQ: "博奈尔、圣尤斯特歇斯和萨巴",
|
||||
BR: "巴西",
|
||||
BS: "巴哈马",
|
||||
BT: "不丹",
|
||||
BV: "布韦岛",
|
||||
BW: "博茨瓦纳",
|
||||
BY: "白俄罗斯",
|
||||
BZ: "伯利兹",
|
||||
CA: "加拿大",
|
||||
CA1: "加拿大",
|
||||
CC: "科科斯(基林)群岛",
|
||||
CD: "刚果民主共和国",
|
||||
CF: "中非共和国",
|
||||
CG: "刚果共和国",
|
||||
CH: "瑞士",
|
||||
CI: "科特迪瓦",
|
||||
CK: "库克群岛",
|
||||
CL: "智利",
|
||||
CM: "喀麦隆",
|
||||
CN: "中国",
|
||||
CO: "哥伦比亚",
|
||||
CR: "哥斯达黎加",
|
||||
CU: "古巴",
|
||||
CV: "佛得角",
|
||||
CW: "库拉索",
|
||||
CX: "圣诞岛",
|
||||
CY: "塞浦路斯",
|
||||
CZ: "捷克共和国",
|
||||
DE: "德国",
|
||||
DG: "迪戈加西亚岛",
|
||||
DJ: "吉布提",
|
||||
DK: "丹麦",
|
||||
DM: "多米尼克",
|
||||
DO: "多米尼加共和国",
|
||||
DZ: "阿尔及利亚",
|
||||
EC: "厄瓜多尔",
|
||||
EE: "爱沙尼亚",
|
||||
EG: "埃及",
|
||||
EH: "西撒哈拉",
|
||||
ER: "厄立特里亚",
|
||||
ES: "西班牙",
|
||||
ET: "埃塞俄比亚",
|
||||
FI: "芬兰",
|
||||
FJ: "斐济",
|
||||
FK: "福克兰群岛",
|
||||
FM: "密克罗尼西亚",
|
||||
FO: "法罗群岛",
|
||||
FR: "法国",
|
||||
GA: "加蓬",
|
||||
GB: "英国",
|
||||
GD: "格林纳达",
|
||||
GE: "格鲁吉亚",
|
||||
GF: "法属圭亚那",
|
||||
GG: "根西岛",
|
||||
GH: "加纳",
|
||||
GI: "直布罗陀",
|
||||
GL: "格陵兰",
|
||||
GM: "冈比亚",
|
||||
GN: "几内亚",
|
||||
GP: "瓜德罗普",
|
||||
GQ: "赤道几内亚",
|
||||
GR: "希腊",
|
||||
GS: "南乔治亚和南桑德威奇群岛",
|
||||
GT: "危地马拉",
|
||||
GU: "关岛",
|
||||
GW: "几内亚比绍",
|
||||
GY: "圭亚那",
|
||||
HK: "中国香港特别行政区",
|
||||
HM: "赫德岛和麦克唐纳群岛",
|
||||
HN: "洪都拉斯",
|
||||
HR: "克罗地亚",
|
||||
HT: "海地",
|
||||
HU: "匈牙利",
|
||||
ID: "印度尼西亚",
|
||||
IE: "爱尔兰",
|
||||
IL: "以色列",
|
||||
IM: "马恩岛",
|
||||
IN: "印度",
|
||||
IO: "英属印度洋领地",
|
||||
IQ: "伊拉克",
|
||||
IR: "伊朗",
|
||||
IS: "冰岛",
|
||||
IT: "意大利",
|
||||
JE: "泽西岛",
|
||||
JM: "牙买加",
|
||||
JO: "约旦",
|
||||
JP: "日本",
|
||||
JP1: "日本",
|
||||
KE: "肯尼亚",
|
||||
KG: "吉尔吉斯斯坦",
|
||||
KH: "柬埔寨",
|
||||
KI: "基里巴斯",
|
||||
KM: "科摩罗",
|
||||
KN: "圣基茨和尼维斯",
|
||||
KP: "朝鲜",
|
||||
KR: "韩国",
|
||||
KR1: "韩国",
|
||||
KR1_UXWAUDIT: "韩国",
|
||||
KW: "科威特",
|
||||
KY: "开曼群岛",
|
||||
KZ: "哈萨克斯坦",
|
||||
LA: "老挝",
|
||||
LB: "黎巴嫩",
|
||||
LC: "圣卢西亚",
|
||||
LI: "列支敦士登",
|
||||
LK: "斯里兰卡",
|
||||
LR: "利比里亚",
|
||||
LS: "莱索托",
|
||||
LT: "立陶宛",
|
||||
LU: "卢森堡",
|
||||
LV: "拉脱维亚",
|
||||
LY: "利比亚",
|
||||
MA: "摩洛哥",
|
||||
MC: "摩纳哥",
|
||||
MD: "摩尔多瓦",
|
||||
ME: "黑山",
|
||||
MF: "圣马丁",
|
||||
MG: "马达加斯加",
|
||||
MH: "马绍尔群岛",
|
||||
MK: "北马其顿",
|
||||
ML: "马里",
|
||||
MM: "缅甸",
|
||||
MN: "蒙古",
|
||||
MO: "中国澳门特别行政区",
|
||||
MP: "北马里亚纳群岛",
|
||||
MQ: "马提尼克",
|
||||
MR: "毛里塔尼亚",
|
||||
MS: "蒙特塞拉特",
|
||||
MT: "马耳他",
|
||||
MU: "毛里求斯",
|
||||
MV: "马尔代夫",
|
||||
MW: "马拉维",
|
||||
MX: "墨西哥",
|
||||
MY: "马来西亚",
|
||||
MZ: "莫桑比克",
|
||||
NA: "纳米比亚",
|
||||
NC: "新喀里多尼亚",
|
||||
NE: "尼日尔",
|
||||
NF: "诺福克岛",
|
||||
NG: "尼日利亚",
|
||||
NI: "尼加拉瓜",
|
||||
NL: "荷兰",
|
||||
NO: "挪威",
|
||||
NP: "尼泊尔",
|
||||
NR: "瑙鲁",
|
||||
NU: "纽埃",
|
||||
NZ: "新西兰",
|
||||
OM: "阿曼",
|
||||
PA: "巴拿马",
|
||||
PE: "秘鲁",
|
||||
PF: "法属玻利尼西亚",
|
||||
PG: "巴布亚新几内亚",
|
||||
PH: "菲律宾",
|
||||
PK: "巴基斯坦",
|
||||
PL: "波兰",
|
||||
PM: "圣皮埃尔和密克隆群岛",
|
||||
PN: "皮特凯恩群岛",
|
||||
PR: "波多黎各",
|
||||
PS: "巴勒斯坦",
|
||||
PT: "葡萄牙",
|
||||
PW: "帕劳",
|
||||
PY: "巴拉圭",
|
||||
QA: "卡塔尔",
|
||||
RE: "留尼汪",
|
||||
RO: "罗马尼亚",
|
||||
RS: "塞尔维亚",
|
||||
RU: "俄罗斯",
|
||||
RW: "卢旺达",
|
||||
SA: "沙特阿拉伯",
|
||||
SB: "索罗门群岛",
|
||||
SC: "塞舌尔",
|
||||
SD: "苏丹",
|
||||
SE: "瑞典",
|
||||
SG: "新加坡",
|
||||
SI: "斯洛文尼亚",
|
||||
SJ: "斯瓦尔巴和扬马延",
|
||||
SK: "斯洛伐克",
|
||||
SL: "塞拉利昂",
|
||||
SM: "圣马利诺",
|
||||
SN: "塞内加尔",
|
||||
SO: "索马里",
|
||||
SR: "苏里南",
|
||||
SS: "南苏丹",
|
||||
ST: "圣多美和普林西比",
|
||||
SV: "萨尔瓦多",
|
||||
SX: "荷属圣马丁",
|
||||
SY: "叙利亚",
|
||||
SZ: "斯威士兰",
|
||||
TC: "特克斯和凯科斯群岛",
|
||||
TD: "乍得",
|
||||
TF: "法属南部领地",
|
||||
TG: "多哥",
|
||||
TH: "泰国",
|
||||
TJ: "塔吉克斯坦",
|
||||
TK: "托克劳群岛",
|
||||
TL: "东帝汶",
|
||||
TM: "土库曼斯坦",
|
||||
TN: "突尼斯",
|
||||
TO: "汤加",
|
||||
TR: "土耳其",
|
||||
TT: "特立尼达和多巴哥",
|
||||
TV: "图瓦卢",
|
||||
TW: "台湾",
|
||||
TZ: "坦桑尼亚",
|
||||
UA: "乌克兰",
|
||||
UG: "乌干达",
|
||||
UM: "美国本土外小岛屿",
|
||||
US: "美国",
|
||||
UY: "乌拉圭",
|
||||
UZ: "乌兹别克斯坦",
|
||||
VA: "梵蒂冈",
|
||||
VC: "圣文森特",
|
||||
VE: "委内瑞拉",
|
||||
VG: "英属维尔京群岛",
|
||||
VI: "美属维尔京群岛",
|
||||
VN: "越南",
|
||||
VN1: "越南",
|
||||
VU: "瓦努阿图",
|
||||
WS: "萨摩亚",
|
||||
YE: "也门",
|
||||
YT: "马约特岛",
|
||||
ZA: "南非",
|
||||
ZM: "赞比亚",
|
||||
ZW: "津巴布韦"
|
||||
AD: "AD",
|
||||
AE: "AE",
|
||||
AF: "AF",
|
||||
AG: "AG",
|
||||
AI: "AI",
|
||||
AL: "AL",
|
||||
AM: "AM",
|
||||
AO: "AO",
|
||||
AQ: "AQ",
|
||||
AR: "AR",
|
||||
AS: "AS",
|
||||
AT: "AT",
|
||||
AU: "AU",
|
||||
AU1: "AU1",
|
||||
AW: "AW",
|
||||
AX: "AX",
|
||||
AZ: "AZ",
|
||||
BA: "BA",
|
||||
BB: "BB",
|
||||
BD: "BD",
|
||||
BE: "BE",
|
||||
BF: "BF",
|
||||
BG: "BG",
|
||||
BH: "BH",
|
||||
BI: "BI",
|
||||
BJ: "BJ",
|
||||
BL: "BL",
|
||||
BM: "BM",
|
||||
BN: "BN",
|
||||
BO: "BO",
|
||||
BQ: "BQ",
|
||||
BR: "BR",
|
||||
BS: "BS",
|
||||
BT: "BT",
|
||||
BV: "BV",
|
||||
BW: "BW",
|
||||
BY: "BY",
|
||||
BZ: "BZ",
|
||||
CA: "CA",
|
||||
CA1: "CA1",
|
||||
CC: "CC",
|
||||
CD: "CD",
|
||||
CF: "CF",
|
||||
CG: "CG",
|
||||
CH: "CH",
|
||||
CI: "CI",
|
||||
CK: "CK",
|
||||
CL: "CL",
|
||||
CM: "CM",
|
||||
CN: "CN",
|
||||
CO: "CO",
|
||||
CR: "CR",
|
||||
CU: "CU",
|
||||
CV: "CV",
|
||||
CW: "CW",
|
||||
CX: "CX",
|
||||
CY: "CY",
|
||||
CZ: "CZ",
|
||||
DE: "DE",
|
||||
DG: "DG",
|
||||
DJ: "DJ",
|
||||
DK: "DK",
|
||||
DM: "DM",
|
||||
DO: "DO",
|
||||
DZ: "DZ",
|
||||
EC: "EC",
|
||||
EE: "EE",
|
||||
EG: "EG",
|
||||
EH: "EH",
|
||||
ER: "ER",
|
||||
ES: "ES",
|
||||
ET: "ET",
|
||||
FI: "FI",
|
||||
FJ: "FJ",
|
||||
FK: "FK",
|
||||
FM: "FM",
|
||||
FO: "FO",
|
||||
FR: "FR",
|
||||
GA: "GA",
|
||||
GB: "GB",
|
||||
GD: "GD",
|
||||
GE: "GE",
|
||||
GF: "GF",
|
||||
GG: "GG",
|
||||
GH: "GH",
|
||||
GI: "GI",
|
||||
GL: "GL",
|
||||
GM: "GM",
|
||||
GN: "GN",
|
||||
GP: "GP",
|
||||
GQ: "GQ",
|
||||
GR: "GR",
|
||||
GS: "GS",
|
||||
GT: "GT",
|
||||
GU: "GU",
|
||||
GW: "GW",
|
||||
GY: "GY",
|
||||
HK: "HK",
|
||||
HM: "HM",
|
||||
HN: "HN",
|
||||
HR: "HR",
|
||||
HT: "HT",
|
||||
HU: "HU",
|
||||
ID: "ID",
|
||||
IE: "IE",
|
||||
IL: "IL",
|
||||
IM: "IM",
|
||||
IN: "IN",
|
||||
IO: "IO",
|
||||
IQ: "IQ",
|
||||
IR: "IR",
|
||||
IS: "IS",
|
||||
IT: "IT",
|
||||
JE: "JE",
|
||||
JM: "JM",
|
||||
JO: "JO",
|
||||
JP: "JP",
|
||||
JP1: "JP1",
|
||||
KE: "KE",
|
||||
KG: "KG",
|
||||
KH: "KH",
|
||||
KI: "KI",
|
||||
KM: "KM",
|
||||
KN: "KN",
|
||||
KP: "KP",
|
||||
KR: "KR",
|
||||
KR1: "KR1",
|
||||
KR1_UXWAUDIT: "KR1_UXWAUDIT",
|
||||
KW: "KW",
|
||||
KY: "KY",
|
||||
KZ: "KZ",
|
||||
LA: "LA",
|
||||
LB: "LB",
|
||||
LC: "LC",
|
||||
LI: "LI",
|
||||
LK: "LK",
|
||||
LR: "LR",
|
||||
LS: "LS",
|
||||
LT: "LT",
|
||||
LU: "LU",
|
||||
LV: "LV",
|
||||
LY: "LY",
|
||||
MA: "MA",
|
||||
MC: "MC",
|
||||
MD: "MD",
|
||||
ME: "ME",
|
||||
MF: "MF",
|
||||
MG: "MG",
|
||||
MH: "MH",
|
||||
MK: "MK",
|
||||
ML: "ML",
|
||||
MM: "MM",
|
||||
MN: "MN",
|
||||
MO: "MO",
|
||||
MP: "MP",
|
||||
MQ: "MQ",
|
||||
MR: "MR",
|
||||
MS: "MS",
|
||||
MT: "MT",
|
||||
MU: "MU",
|
||||
MV: "MV",
|
||||
MW: "MW",
|
||||
MX: "MX",
|
||||
MY: "MY",
|
||||
MZ: "MZ",
|
||||
NA: "NA",
|
||||
NC: "NC",
|
||||
NE: "NE",
|
||||
NF: "NF",
|
||||
NG: "NG",
|
||||
NI: "NI",
|
||||
NL: "NL",
|
||||
NO: "NO",
|
||||
NP: "NP",
|
||||
NR: "NR",
|
||||
NU: "NU",
|
||||
NZ: "NZ",
|
||||
OM: "OM",
|
||||
PA: "PA",
|
||||
PE: "PE",
|
||||
PF: "PF",
|
||||
PG: "PG",
|
||||
PH: "PH",
|
||||
PK: "PK",
|
||||
PL: "PL",
|
||||
PM: "PM",
|
||||
PN: "PN",
|
||||
PR: "PR",
|
||||
PS: "PS",
|
||||
PT: "PT",
|
||||
PW: "PW",
|
||||
PY: "PY",
|
||||
QA: "QA",
|
||||
RE: "RE",
|
||||
RO: "RO",
|
||||
RS: "RS",
|
||||
RU: "RU",
|
||||
RW: "RW",
|
||||
SA: "SA",
|
||||
SB: "SB",
|
||||
SC: "SC",
|
||||
SD: "SD",
|
||||
SE: "SE",
|
||||
SG: "SG",
|
||||
SI: "SI",
|
||||
SJ: "SJ",
|
||||
SK: "SK",
|
||||
SL: "SL",
|
||||
SM: "SM",
|
||||
SN: "SN",
|
||||
SO: "SO",
|
||||
SR: "SR",
|
||||
SS: "SS",
|
||||
ST: "ST",
|
||||
SV: "SV",
|
||||
SX: "SX",
|
||||
SY: "SY",
|
||||
SZ: "SZ",
|
||||
TC: "TC",
|
||||
TD: "TD",
|
||||
TF: "TF",
|
||||
TG: "TG",
|
||||
TH: "TH",
|
||||
TJ: "TJ",
|
||||
TK: "TK",
|
||||
TL: "TL",
|
||||
TM: "TM",
|
||||
TN: "TN",
|
||||
TO: "TO",
|
||||
TR: "TR",
|
||||
TT: "TT",
|
||||
TV: "TV",
|
||||
TW: "TW",
|
||||
TZ: "TZ",
|
||||
UA: "UA",
|
||||
UG: "UG",
|
||||
UM: "UM",
|
||||
US: "US",
|
||||
UY: "UY",
|
||||
UZ: "UZ",
|
||||
VA: "VA",
|
||||
VC: "VC",
|
||||
VE: "VE",
|
||||
VG: "VG",
|
||||
VI: "VI",
|
||||
VN: "VN",
|
||||
VN1: "VN1",
|
||||
VU: "VU",
|
||||
WS: "WS",
|
||||
YE: "YE",
|
||||
YT: "YT",
|
||||
ZA: "ZA",
|
||||
ZM: "ZM",
|
||||
ZW: "ZW"
|
||||
};
|
||||
|
||||
export function getCountryName(code) {
|
||||
return CountryCode[code] || null;
|
||||
if (!code) return null;
|
||||
|
||||
// 使用 i18n 获取国家名称翻译
|
||||
const countryName = i18n.global.t(`countries.${code}`);
|
||||
|
||||
// 如果找不到翻译,返回 null
|
||||
return countryName === `countries.${code}` ? null : countryName;
|
||||
}
|
||||
@@ -1,117 +1,225 @@
|
||||
// pythonBridge.js
|
||||
import { ref, onMounted } from 'vue';
|
||||
const bridge = ref(null);
|
||||
import { ElMessage } from 'element-plus';
|
||||
const pyBridge = ref(null);
|
||||
// 初始化 QWebChannel
|
||||
const initBridge = () => {
|
||||
if (/localhost/.test(window.location.href)) return
|
||||
new QWebChannel(qt.webChannelTransport, (channel) => {
|
||||
bridge.value = channel.objects.bridge;
|
||||
pyBridge.value = channel.objects.bridge;
|
||||
});
|
||||
};
|
||||
export function usePythonBridge() {
|
||||
|
||||
|
||||
|
||||
|
||||
// 调用 Python 方法
|
||||
const fetchDataConfig = (data) => {
|
||||
//删除前端储存数据
|
||||
const deleteStorageData = (data) => {
|
||||
return new Promise((resolve, reject) => {
|
||||
if (bridge.value) {
|
||||
bridge.value.fetchDataConfig(data, function (result) {
|
||||
if (pyBridge.value) {
|
||||
pyBridge.value.deleteAccountInfo(JSON.stringify(data),function (result) {
|
||||
resolve(result);
|
||||
});
|
||||
}else{
|
||||
console.log("pyBridge is null未连接上")
|
||||
}
|
||||
|
||||
|
||||
});
|
||||
};
|
||||
|
||||
// 查询获取主播的数据
|
||||
const fetchDataCount = () => {
|
||||
//获取前端储存数据
|
||||
const getStorageData = (data) => {
|
||||
return new Promise((resolve, reject) => {
|
||||
if (bridge.value) {
|
||||
bridge.value.fetchDataCount(function (result) {
|
||||
if (pyBridge.value) {
|
||||
pyBridge.value.readAccountInfo(JSON.stringify(data),function (result) {
|
||||
resolve(result);
|
||||
});
|
||||
}else{
|
||||
console.log("pyBridge is null未连接上")
|
||||
}
|
||||
});
|
||||
};
|
||||
//设置前端储存数据
|
||||
const setStorageData = (data) => {
|
||||
return new Promise((resolve, reject) => {
|
||||
if (pyBridge.value) {
|
||||
pyBridge.value.storageAccountInfo(JSON.stringify(data),function (result) {
|
||||
resolve(result);
|
||||
});
|
||||
}else{
|
||||
console.log("pyBridge is null未连接上")
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
//设置储存数据
|
||||
const storageSetInfos = (data) => {
|
||||
return new Promise((resolve, reject) => {
|
||||
if (pyBridge.value) {
|
||||
pyBridge.value.storageSetInfo(JSON.stringify(data),function (result) {
|
||||
resolve(result);
|
||||
});
|
||||
}else{
|
||||
console.log("pyBridge is null未连接上")
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
//设置储存数据
|
||||
const readSetInfos = (data) => {
|
||||
return new Promise((resolve, reject) => {
|
||||
if (pyBridge.value) {
|
||||
pyBridge.value.readSetInfo(JSON.stringify(data),function (result) {
|
||||
resolve(result);
|
||||
});
|
||||
}else{
|
||||
console.log("pyBridge is null未连接上")
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
// 查询获取大哥的数据
|
||||
const controlTask = (data) => {
|
||||
return new Promise((resolve, reject) => {
|
||||
if (pyBridge.value) {
|
||||
pyBridge.value.control_task(data,function (result) {
|
||||
resolve(result);
|
||||
});
|
||||
}else{
|
||||
console.log("pyBridge is null未连接上")
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
//总数有效数
|
||||
const getBrotherInfo = () => {
|
||||
return new Promise((resolve, reject) => {
|
||||
if (pyBridge.value) {
|
||||
pyBridge.value.getBrotherInfo(function (result) {
|
||||
resolve(JSON.parse(result));
|
||||
});
|
||||
}else{
|
||||
console.log("pyBridge is null未连接上")
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
// 打开tk后台
|
||||
const loginTikTok = () => {
|
||||
if (bridge.value) {
|
||||
bridge.value.loginTikTok(function (result) {
|
||||
|
||||
if (pyBridge.value) {
|
||||
pyBridge.value.loginTikTok(function (result) {
|
||||
});
|
||||
}else{
|
||||
console.log("pyBridge is null未连接上")
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
// 登录tk后台
|
||||
const loginBackStage = (data) => {
|
||||
if (bridge.value) {
|
||||
if (data.index == 0) {
|
||||
bridge.value.loginBackStage(JSON.stringify(data));
|
||||
} else if (data.index == 1) {
|
||||
bridge.value.loginBackStageCopy(JSON.stringify(data));
|
||||
//指定直播间
|
||||
const Specifystreaming = (data) => {
|
||||
return new Promise((resolve, reject) => {
|
||||
if (pyBridge.value) {
|
||||
pyBridge.value.find_big_brother_in_rooms(data,function (result) {
|
||||
resolve(result);
|
||||
});
|
||||
}else{
|
||||
console.log("pyBridge is null未连接上")
|
||||
}
|
||||
});
|
||||
};
|
||||
//储存直播间id
|
||||
const setStorageStreamId = (data) => {
|
||||
return new Promise((resolve, reject) => {
|
||||
if (pyBridge.value) {
|
||||
pyBridge.value.saveFrontString(JSON.stringify(data),function (result) {
|
||||
resolve(result);
|
||||
});
|
||||
}else{
|
||||
console.log("pyBridge is null未连接上")
|
||||
}
|
||||
});
|
||||
};
|
||||
//获取直播间id
|
||||
const getStorageStreamId = (data) => {
|
||||
return new Promise((resolve, reject) => {
|
||||
if (pyBridge.value) {
|
||||
pyBridge.value.loadFrontStringRaw(JSON.stringify(data),function (result) {
|
||||
resolve(result);
|
||||
});
|
||||
}else{
|
||||
console.log("pyBridge is null未连接上")
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
}
|
||||
const setClipboards = (data) => {
|
||||
return new Promise((resolve, reject) => {
|
||||
if (pyBridge.value) {
|
||||
pyBridge.value.setClipboard(JSON.stringify(data),function (result) {
|
||||
resolve(result);
|
||||
});
|
||||
}else{
|
||||
console.log("pyBridge is null未连接上")
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
//跳转到主播页面
|
||||
const givePyAnchorId = (id) => {
|
||||
|
||||
if (bridge.value) {
|
||||
bridge.value.givePyAnchorId(id, function (result) {
|
||||
|
||||
console.log("id",id);
|
||||
if (pyBridge.value) {
|
||||
pyBridge.value.givePyAnchorId(id, function (result) {
|
||||
});
|
||||
}
|
||||
};
|
||||
//跳转到主播页面
|
||||
const openAnchorIdRooms = (id) => {
|
||||
console.log("id",id);
|
||||
if (pyBridge.value) {
|
||||
pyBridge.value.openAnchorIdRoom(id, function (result) {
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
//查询登录状态
|
||||
const backStageloginStatus = () => {
|
||||
return new Promise((resolve, reject) => {
|
||||
if (bridge.value) {
|
||||
bridge.value.backStageloginStatus(function (result) {
|
||||
resolve(result);
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
};
|
||||
//查询登录状态
|
||||
const backStageloginStatusCopy = () => {
|
||||
return new Promise((resolve, reject) => {
|
||||
if (bridge.value) {
|
||||
bridge.value.backStageloginStatusCopy(function (result) {
|
||||
resolve(result);
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
};
|
||||
|
||||
//导出表格
|
||||
const exportToExcel = (data) => {
|
||||
if (bridge.value) {
|
||||
bridge.value.exportToExcel(JSON.stringify(data));
|
||||
if (pyBridge .value) {
|
||||
pyBridge .value.exportToExcel(JSON.stringify(data));
|
||||
}
|
||||
|
||||
};
|
||||
const stopScript = () => {
|
||||
if (pyBridge .value) {
|
||||
pyBridge .value.stopScript();
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
|
||||
//获取版本号
|
||||
const getVersion = () => {
|
||||
return new Promise((resolve, reject) => {
|
||||
if (pyBridge.value) {
|
||||
pyBridge.value.currentVersion(function (result) {
|
||||
resolve(result);
|
||||
});
|
||||
}
|
||||
});
|
||||
};
|
||||
// 在组件挂载时初始化桥接
|
||||
onMounted(initBridge);
|
||||
|
||||
return {
|
||||
fetchDataConfig,
|
||||
fetchDataCount,
|
||||
loginBackStage,
|
||||
loginTikTok,
|
||||
exportToExcel,
|
||||
stopScript,
|
||||
controlTask,
|
||||
getBrotherInfo,
|
||||
getVersion,
|
||||
givePyAnchorId,
|
||||
backStageloginStatus,
|
||||
backStageloginStatusCopy,
|
||||
exportToExcel
|
||||
getStorageData,
|
||||
setStorageData,
|
||||
deleteStorageData,
|
||||
Specifystreaming,
|
||||
setStorageStreamId,
|
||||
getStorageStreamId,
|
||||
openAnchorIdRooms,
|
||||
storageSetInfos,
|
||||
readSetInfos,
|
||||
setClipboards
|
||||
};
|
||||
}
|
||||
@@ -1,45 +1,77 @@
|
||||
export function setToken(token) {
|
||||
localStorage.setItem('token', token);
|
||||
|
||||
import { usePythonBridge} from "@/utils/pythonBridge";
|
||||
|
||||
const { getStorageData, setStorageData,deleteStorageData} = usePythonBridge();
|
||||
import { ElMessage } from 'element-plus';
|
||||
|
||||
export async function setToken(token) {
|
||||
const res = await setStorageData({key: 'token',data: token}).then(res => {
|
||||
});
|
||||
}
|
||||
|
||||
export function getToken() {
|
||||
return localStorage.getItem('token');
|
||||
export async function getToken() {
|
||||
const res = await getStorageData({ key: 'token' });
|
||||
return JSON.parse(res);
|
||||
}
|
||||
|
||||
export function removeToken() {
|
||||
localStorage.removeItem('token');
|
||||
export async function removeToken() {
|
||||
const res = deleteStorageData({key: 'token'});
|
||||
}
|
||||
|
||||
export function setUser(user) {
|
||||
|
||||
localStorage.setItem('user', JSON.stringify(user));
|
||||
export async function setUser(user) {
|
||||
const res = await setStorageData({key: 'user',data: user}).then(res => {
|
||||
});
|
||||
}
|
||||
|
||||
export function getUser() {
|
||||
return JSON.parse(localStorage.getItem('user'));
|
||||
export async function getUser() {
|
||||
const res = await getStorageData({ key: 'user' });
|
||||
return JSON.parse(res);
|
||||
}
|
||||
|
||||
export function setNumData(numData) {
|
||||
localStorage.setItem('num', JSON.stringify(numData));
|
||||
export function setuserprmisson() {
|
||||
return new Promise((resolve, reject) => {
|
||||
const res = getStorageData({ key: 'user' });
|
||||
resolve(res);
|
||||
});
|
||||
}
|
||||
export function getNumData() {
|
||||
return JSON.parse(localStorage.getItem('num'));
|
||||
|
||||
export async function setNumData(numData) {
|
||||
const res = await setStorageData({key: 'num',data: numData})
|
||||
}
|
||||
|
||||
export async function getNumData() {
|
||||
const res = await getStorageData({ key: 'num' });
|
||||
return JSON.parse(res);
|
||||
}
|
||||
|
||||
|
||||
// 导出一个函数,用于设置用户密码
|
||||
export function setUserPass(userdata) {
|
||||
localStorage.setItem('userPass', JSON.stringify(userdata));
|
||||
export async function setUserPass(userdata) {
|
||||
const res = await setStorageData({key: 'userPass',data:userdata})
|
||||
}
|
||||
// 导出一个函数,用于获取用户密码
|
||||
export function getUserPass() {
|
||||
return JSON.parse(localStorage.getItem('userPass'));
|
||||
export async function getUserPass() {
|
||||
const res = await getStorageData({ key: 'userPass' });
|
||||
return JSON.parse(res);
|
||||
}
|
||||
|
||||
// 用于设置tk账户密码
|
||||
export function setTkUser(userdata) {
|
||||
localStorage.setItem('tkuser', JSON.stringify(userdata));
|
||||
export async function setTkUser(userdata) {
|
||||
const res = await setStorageData({key: 'tkuser',data: userdata})
|
||||
}
|
||||
// 用于获取tk账户密码
|
||||
export function getTkUser() {
|
||||
return JSON.parse(localStorage.getItem('tkuser'));
|
||||
}
|
||||
|
||||
export async function getTkUser() {
|
||||
const res = await getStorageData({ key: 'tkuser' });
|
||||
return JSON.parse(res);
|
||||
}
|
||||
|
||||
// 用于列表筛选条件
|
||||
export async function setSerch(data) {
|
||||
const res = await setStorageData({key: 'Serch',data: data})
|
||||
}
|
||||
|
||||
// 用于获取列表筛选条件
|
||||
export async function getSerch() {
|
||||
const res = await getStorageData({ key: 'Serch' });
|
||||
return JSON.parse(res);
|
||||
}
|
||||
|
||||
@@ -1,295 +1,380 @@
|
||||
<template>
|
||||
<div class="main">
|
||||
<div class="container">
|
||||
<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></div>
|
||||
<span>
|
||||
网络设置
|
||||
</span>
|
||||
</div>
|
||||
<div class="setup-item center-justify">
|
||||
<div></div>
|
||||
<span>
|
||||
简体中文
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="center-line" style="margin-top: 40px;">
|
||||
<!-- logo -->
|
||||
<div class="logo">
|
||||
<div class="center-justify" style="height: 80px; width: 300px;">
|
||||
<img style="margin-right: 20px;" src="@/assets/logo.png">
|
||||
<img src="@/assets/logotext.png">
|
||||
</div>
|
||||
</div>
|
||||
<div class="main">
|
||||
<div class="container">
|
||||
<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></div>
|
||||
<span>{{ $t('common.networkSettings') }}</span>
|
||||
</div>
|
||||
<!-- <div class="setup-item center-justify"> -->
|
||||
<div class="">
|
||||
<el-select
|
||||
v-model="currentLanguage"
|
||||
:placeholder="$t('common.language')"
|
||||
@change="changeLanguage"
|
||||
size="small"
|
||||
style="width: 120px;"
|
||||
>
|
||||
<el-option
|
||||
:label="$t('common.simplifiedChinese')"
|
||||
value="zh-CN"
|
||||
/>
|
||||
<el-option
|
||||
:label="$t('common.english')"
|
||||
value="en-US"
|
||||
/>
|
||||
</el-select>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="center-line" style="margin-top: 40px">
|
||||
<!-- logo -->
|
||||
<div class="logo">
|
||||
<!-- <div class="center-justify" style="height: 80px; width: 300px;">
|
||||
<img style="height: 100%;" src="@/assets/logotext.png">
|
||||
</div> -->
|
||||
</div>
|
||||
|
||||
<!-- From -->
|
||||
<div class="from">
|
||||
<div class="from-title center-justify">
|
||||
<div>账号登陆</div>
|
||||
</div>
|
||||
<!-- From -->
|
||||
<div class="from">
|
||||
<div class="from-title center-justify">
|
||||
<div>{{ $t('common.accountLogin') }}</div>
|
||||
</div>
|
||||
|
||||
<div class="from-input">
|
||||
<el-form label-position="left" label-width="100px" :model="formData">
|
||||
<div class="from-input">
|
||||
<el-form label-position="left" label-width="100px" :model="formData">
|
||||
<div class="from-input-item1">
|
||||
<img src="@/assets/username.png" alt="" />
|
||||
<el-input
|
||||
style="height: 25px"
|
||||
v-model="formData.tenantName"
|
||||
:placeholder="$t('common.tenantName')"
|
||||
clearable
|
||||
@keyup.enter="onSubmit"
|
||||
/>
|
||||
</div>
|
||||
<div class="from-input-item1">
|
||||
<img src="@/assets/username.png" alt="" />
|
||||
<el-input
|
||||
style="height: 25px"
|
||||
v-model="formData.userId"
|
||||
:placeholder="$t('common.account')"
|
||||
clearable
|
||||
@keyup.enter="onSubmit"
|
||||
/>
|
||||
</div>
|
||||
<div class="from-input-item1">
|
||||
<img src="@/assets/password.png" alt="" />
|
||||
<el-input
|
||||
style="height: 25px"
|
||||
v-model="formData.password"
|
||||
type="password"
|
||||
:placeholder="$t('common.password')"
|
||||
show-password
|
||||
@keyup.enter="onSubmit"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div class="from-input-item1">
|
||||
<img src="@/assets/username.png" alt="">
|
||||
<el-input style="height: 25px;" v-model="formData.userId" placeholder="账号" clearable
|
||||
@keyup.enter="onSubmit" />
|
||||
</div>
|
||||
<div class="from-input-item1">
|
||||
<img src="@/assets/password.png" alt="">
|
||||
<el-input style="height: 25px; " v-model="formData.password" type="password"
|
||||
placeholder="密码" show-password @keyup.enter="onSubmit" />
|
||||
</div>
|
||||
|
||||
<div class="from-input-item">
|
||||
<el-button class="loginButton" color="#8f7ee7" type="primary"
|
||||
@click="onSubmit">登录</el-button>
|
||||
</div>
|
||||
</el-form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="from-input-item">
|
||||
<el-button
|
||||
class="loginButton"
|
||||
color="#8f7ee7"
|
||||
type="primary"
|
||||
@click="onSubmit"
|
||||
>{{ $t('common.login') }}</el-button
|
||||
>
|
||||
</div>
|
||||
</el-form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="version center-justify">{{ $t('common.version') }}:{{ version }}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref, reactive, onMounted } from 'vue';
|
||||
import { useRouter } from 'vue-router';
|
||||
import { login } from '@/api/account';
|
||||
import { getToken, setToken, setUser, setUserPass, getUserPass } from '@/utils/storage';
|
||||
import { ElLoading } from 'element-plus';
|
||||
import { ref, reactive, onMounted } from "vue";
|
||||
import { useRouter } from "vue-router";
|
||||
import { useI18n } from 'vue-i18n';
|
||||
import { login, rentgetloginID } from "@/api/account";
|
||||
import { getToken, setToken, setUser, setUserPass, getUserPass } from "@/utils/storage";
|
||||
import { ElLoading } from "element-plus";
|
||||
import { usePythonBridge } from "@/utils/pythonBridge";
|
||||
import { ElMessage } from 'element-plus';
|
||||
import { tokenStore,UserStore } from '@/stores/notice'
|
||||
|
||||
const { t, locale } = useI18n();
|
||||
const tokenCache = tokenStore()
|
||||
const userCache = UserStore()
|
||||
const { getVersion } = usePythonBridge();
|
||||
let version = ref("0.0.0");
|
||||
|
||||
// 当前语言
|
||||
const currentLanguage = ref(localStorage.getItem('language') || 'zh-CN');
|
||||
|
||||
onMounted(() => {
|
||||
setTimeout(() => {
|
||||
getVersion().then((res) => {
|
||||
version.value = res;
|
||||
});
|
||||
getpassword();
|
||||
}, 500);
|
||||
});
|
||||
|
||||
async function getpassword(){
|
||||
const res = await getUserPass();
|
||||
formData.value = {
|
||||
tenantName: res == null ? "" : res.tenantName,
|
||||
userId: res == null ? "" : res.userId,
|
||||
password: res == null ? "" : res.password,
|
||||
};
|
||||
}
|
||||
|
||||
// 切换语言
|
||||
const changeLanguage = (lang) => {
|
||||
locale.value = lang;
|
||||
currentLanguage.value = lang;
|
||||
localStorage.setItem('language', lang);
|
||||
// 重新加载页面以应用Element Plus语言包
|
||||
window.location.reload();
|
||||
};
|
||||
|
||||
const router = useRouter();
|
||||
|
||||
const formData = ref({
|
||||
userId: getUserPass() == null ? '' : getUserPass().userId,
|
||||
password: getUserPass() == null ? '' : getUserPass().password,
|
||||
});
|
||||
|
||||
const formData = ref({});
|
||||
|
||||
const onSubmit = () => {
|
||||
const loading = ElLoading.service({
|
||||
lock: true,
|
||||
text: 'Loading',
|
||||
background: 'rgba(0, 0, 0, 0.7)',
|
||||
});
|
||||
setUserPass(formData.value);
|
||||
login({
|
||||
userId: formData.value.userId,
|
||||
password: formData.value.password,
|
||||
}).then((res) => {
|
||||
loading.close();
|
||||
console.log(res)
|
||||
if (res) {
|
||||
if (res.activeYn == 'Y') {
|
||||
setToken(res.currcode);
|
||||
setUser(res);
|
||||
router.push('/nav');
|
||||
} else {
|
||||
alert('账号未启用');
|
||||
}
|
||||
const loading = ElLoading.service({
|
||||
lock: true,
|
||||
text: "Loading",
|
||||
background: "rgba(0, 0, 0, 0.7)",
|
||||
});
|
||||
rentgetloginID({
|
||||
name: formData.value.tenantName,
|
||||
})
|
||||
.then((res) => {
|
||||
console.log(res);
|
||||
|
||||
} else {
|
||||
alert('账号或密码错误');
|
||||
}
|
||||
|
||||
}).catch((err) => {
|
||||
loading.close();
|
||||
});
|
||||
login({
|
||||
username: formData.value.userId,
|
||||
tenantId: res,
|
||||
password: formData.value.password,
|
||||
})
|
||||
.then((res) => {
|
||||
loading.close();
|
||||
console.log("123123123123",res);
|
||||
setToken(res.tokenValue);
|
||||
tokenCache.setToken(res.tokenValue)
|
||||
userCache.setUser(res)
|
||||
setUser(res);
|
||||
setUserPass(formData.value);
|
||||
router.push("/nav");
|
||||
})
|
||||
.catch((err) => {
|
||||
loading.close();
|
||||
});
|
||||
})
|
||||
.catch((err) => {
|
||||
loading.close();
|
||||
console.log(err);
|
||||
});
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="less">
|
||||
.main {
|
||||
width: 1600px;
|
||||
height: 900px;
|
||||
overflow: hidden;
|
||||
box-sizing: border-box;
|
||||
width: 1600px;
|
||||
height: 900px;
|
||||
overflow: hidden;
|
||||
box-sizing: border-box;
|
||||
|
||||
/* 页面无法选中 */
|
||||
-webkit-user-select: none;
|
||||
-moz-user-select: none;
|
||||
-ms-user-select: none;
|
||||
user-select: none;
|
||||
/* 页面无法选中 */
|
||||
-webkit-user-select: none;
|
||||
-moz-user-select: none;
|
||||
-ms-user-select: none;
|
||||
user-select: none;
|
||||
|
||||
.container {
|
||||
display: flex;
|
||||
box-sizing: border-box;
|
||||
width: 1600px;
|
||||
height: 900px;
|
||||
.container {
|
||||
display: flex;
|
||||
box-sizing: border-box;
|
||||
width: 1600px;
|
||||
height: 900px;
|
||||
|
||||
.right {
|
||||
box-sizing: border-box;
|
||||
position: relative;
|
||||
width: 1600px;
|
||||
height: 900px;
|
||||
padding: 20px 40px 20px 50px;
|
||||
border-left: 3px solid #23516e;
|
||||
position: relative;
|
||||
/* 添加 position: relative */
|
||||
overflow: hidden;
|
||||
/* 防止内容溢出 */
|
||||
.right {
|
||||
box-sizing: border-box;
|
||||
position: relative;
|
||||
width: 1600px;
|
||||
height: 900px;
|
||||
padding: 20px 40px 20px 50px;
|
||||
border-left: 3px solid #23516e;
|
||||
position: relative;
|
||||
/* 添加 position: relative */
|
||||
overflow: hidden;
|
||||
/* 防止内容溢出 */
|
||||
|
||||
.background-video {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
z-index: -1;
|
||||
/* 确保视频在内容之下 */
|
||||
}
|
||||
.version {
|
||||
color: #fff;
|
||||
position: absolute;
|
||||
font-size: 20px;
|
||||
bottom: 20px;
|
||||
left: calc(50% - 50px);
|
||||
// box-sizing: border-box;
|
||||
// width: 1600px;
|
||||
}
|
||||
|
||||
.setup {
|
||||
display: flex;
|
||||
color: #fff;
|
||||
.background-video {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
z-index: -1;
|
||||
/* 确保视频在内容之下 */
|
||||
}
|
||||
|
||||
.setup-item {
|
||||
padding: 10px 6px;
|
||||
display: flex;
|
||||
.setup {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
color: #fff;
|
||||
|
||||
div {
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
border-radius: 50%;
|
||||
background-color: rgb(255, 255, 255);
|
||||
margin-right: 5px;
|
||||
}
|
||||
}
|
||||
}
|
||||
.setup-item {
|
||||
padding: 10px 6px;
|
||||
display: flex;
|
||||
|
||||
.logo {
|
||||
padding: 20px 0;
|
||||
}
|
||||
div {
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
border-radius: 50%;
|
||||
background-color: rgb(255, 255, 255);
|
||||
margin-right: 5px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.from {
|
||||
width: 420px;
|
||||
height: 320px;
|
||||
color: #107A4E;
|
||||
background-color: #ffffff44;
|
||||
border-radius: 20px;
|
||||
border: 1px solid #fff;
|
||||
padding: 32px;
|
||||
box-sizing: border-box;
|
||||
.logo {
|
||||
padding: 20px 0;
|
||||
height: 80px;
|
||||
}
|
||||
|
||||
.from-title {
|
||||
font-family: Source Han Sans SC;
|
||||
font-weight: 500;
|
||||
font-size: 24px;
|
||||
color: #107A4E;
|
||||
line-height: 37px;
|
||||
.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;
|
||||
}
|
||||
}
|
||||
div {
|
||||
font-size: 20px;
|
||||
font-weight: 600;
|
||||
// border-bottom: 4px solid #1db97d;
|
||||
}
|
||||
}
|
||||
|
||||
.from-input {
|
||||
width: 100%;
|
||||
padding: 15px 0;
|
||||
.from-input {
|
||||
width: 100%;
|
||||
padding: 15px 0;
|
||||
|
||||
.from-input-item {
|
||||
display: flex;
|
||||
padding: 8px 0;
|
||||
.from-input-item {
|
||||
display: flex;
|
||||
padding: 8px 0;
|
||||
|
||||
.from-input-item-title {
|
||||
color: #107A4E;
|
||||
font-size: 18px;
|
||||
font-weight: 500;
|
||||
width: 80px;
|
||||
height: 50px;
|
||||
}
|
||||
.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;
|
||||
.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;
|
||||
}
|
||||
}
|
||||
|
||||
font-family: Source Han Sans SC;
|
||||
font-weight: 500;
|
||||
font-size: 18px;
|
||||
color: #107A4E;
|
||||
line-height: 37px;
|
||||
}
|
||||
}
|
||||
|
||||
.from-input-item1 {
|
||||
display: flex;
|
||||
width: 359px;
|
||||
height: 50px;
|
||||
background: rgba(147, 174, 158, 0.37);
|
||||
border-radius: 24px;
|
||||
border: 1px solid #FFFFFF;
|
||||
padding: 12px 25px 13px 25px;
|
||||
box-sizing: border-box;
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.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 {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.center-justify {
|
||||
display: flex;
|
||||
justify-content: space-around;
|
||||
align-items: center;
|
||||
display: flex;
|
||||
justify-content: space-around;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.center-align {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
.center-flex {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.el-input__wrapper {
|
||||
--el-input-focus-border-color: rgba(255, 255, 0, 0);
|
||||
--el-menu-hover-bg-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);
|
||||
}
|
||||
</style>
|
||||
|
||||
<style scoped>
|
||||
<style scoped lang="less">
|
||||
::v-deep(.el-input__wrapper) {
|
||||
background-color: rgba(255, 0, 0, 0);
|
||||
box-shadow: none;
|
||||
|
||||
background-color: rgba(255, 0, 0, 0);
|
||||
box-shadow: none;
|
||||
}
|
||||
|
||||
::v-deep(.el-input__inner) {
|
||||
color: #107A4E;
|
||||
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
::v-deep(.el-input__inner::placeholder) {
|
||||
color: #107A4E;
|
||||
color: @bg-color;
|
||||
}
|
||||
</style>
|
||||
</style>
|
||||
|
||||
77
src/views/hosts/Home.vue
Normal file
@@ -0,0 +1,77 @@
|
||||
<template>
|
||||
<div class="home">
|
||||
<!-- <div id="main" class="main"></div> -->
|
||||
<div class="noData">
|
||||
暂无数据
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
// <script setup>
|
||||
// import { ref, watch, onMounted, onUpdated, onUnmounted } from "vue";
|
||||
// const refname = ref('');
|
||||
|
||||
// const echarts = require('echarts/lib/echarts');
|
||||
// require('echarts/lib/component/grid');
|
||||
// require('echarts/lib/chart/bar');
|
||||
|
||||
// const initChart = () => {
|
||||
// var chartDom = document.getElementById('main');
|
||||
// var myChart = echarts.init(chartDom);
|
||||
// var option = {
|
||||
// xAxis: {
|
||||
// type: 'category',
|
||||
// data: ['用户量', '123', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun']
|
||||
// },
|
||||
// yAxis: {
|
||||
// type: 'value'
|
||||
// },
|
||||
// series: [
|
||||
// {
|
||||
// data: [120, 200, 150, 80, 70, 110, 130],
|
||||
// type: 'bar'
|
||||
// }
|
||||
// ]
|
||||
// };
|
||||
// myChart.setOption(option);
|
||||
// };
|
||||
|
||||
// watch(refname, (newQuestion) => {
|
||||
// // 变化后执行
|
||||
// // 如果 refname 的变化影响图表数据,可以在这里更新 option 并调用 myChart.setOption(option)
|
||||
// });
|
||||
|
||||
// onMounted(() => {
|
||||
// initChart();
|
||||
// });
|
||||
|
||||
// onUpdated(() => {
|
||||
// // 组件更新后执行
|
||||
// // 如果需要根据更新重新初始化图表或更新数据,可以在这里添加逻辑
|
||||
// });
|
||||
|
||||
// onUnmounted(() => {
|
||||
// // 组件销毁前执行
|
||||
// // 如果需要销毁图表实例以释放资源,可以在这里添加逻辑
|
||||
// });
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.home {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background-color: #ffffff;
|
||||
border-radius: 10px;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
.noData{
|
||||
font-size: 20px;
|
||||
color: #999999;
|
||||
}
|
||||
.main{
|
||||
width: 40%;
|
||||
height: 40%;
|
||||
}
|
||||
</style>
|
||||
288
src/views/hosts/ai/LanguageManagement.vue
Normal file
@@ -0,0 +1,288 @@
|
||||
<template>
|
||||
<div class="language-management">
|
||||
<div class="content">
|
||||
<div class="languagetitle">
|
||||
<div class="title">语言管理</div>
|
||||
|
||||
<div class="add" @click="dialogVisible = true">
|
||||
<img class="add-img" src="@/assets/plus2.png" alt="" />
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<!-- 语言列表 -->
|
||||
<div class="languagelist">
|
||||
<el-table
|
||||
:data="tableData"
|
||||
stripe
|
||||
style="width: 100%; margin-top: 10px"
|
||||
max-height="700"
|
||||
>
|
||||
<el-table-column prop="language" label="语言名称" />
|
||||
<el-table-column prop="" label="" />
|
||||
<el-table-column prop="" label="" />
|
||||
<el-table-column prop="" label="" />
|
||||
<el-table-column label="操作">
|
||||
|
||||
<template #default="scope">
|
||||
<el-button size="small" @click="handleEdit(scope.$index, scope.row)">
|
||||
修改
|
||||
</el-button>
|
||||
<el-button
|
||||
size="small"
|
||||
type="danger"
|
||||
@click="handleDelete(scope.$index, scope.row)"
|
||||
>
|
||||
删除
|
||||
</el-button>
|
||||
</template>
|
||||
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- 编辑弹窗 -->
|
||||
<el-drawer v-model="dialogVisible" :with-header="false" @close="dialogVisible = false, languageNamedeta = {}">
|
||||
<div class="dialog-content">
|
||||
<div class="dialog-title">语言{{languageNamedeta.id? '编辑' : '新增'}}</div>
|
||||
<el-input
|
||||
v-model="languageNamedeta.language"
|
||||
style="width: 100%; margin-top: 20px"
|
||||
:rows="3"
|
||||
type="textarea"
|
||||
placeholder="请输入语言内容"
|
||||
/>
|
||||
<div class="dialog-btn">
|
||||
<div class="dialogSave" @click="languageSave">保存</div>
|
||||
<div class="dialogCancel" @click="dialogVisible = false">取消</div>
|
||||
</div>
|
||||
</div>
|
||||
</el-drawer>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ElMessage, ElMessageBox } from "element-plus";
|
||||
import { getLanguageList,deleteLanguage,editLanguage,addLanguage} from "@/api/account";
|
||||
import {
|
||||
ref, // 响应式基础
|
||||
watch, // 侦听器
|
||||
onMounted, // 组件挂载完成后执行
|
||||
onUpdated, // 组件更新后执行
|
||||
onUnmounted, // 组件销毁前执行
|
||||
} from "vue";
|
||||
const refname = ref("");
|
||||
const tableData = ref([]);
|
||||
const dialogVisible = ref(false);
|
||||
let languageNamedeta = ref({});// 编辑添加弹窗数据
|
||||
// 编辑弹窗
|
||||
function handleEdit(index, row) {
|
||||
dialogVisible.value = true;
|
||||
languageNamedeta.value = row;
|
||||
}
|
||||
// 保存语言
|
||||
function languageSave() {
|
||||
if (languageNamedeta.value.language == null) {
|
||||
ElMessage({
|
||||
type: "error",
|
||||
message: "请输入语言内容",
|
||||
});
|
||||
return;
|
||||
}
|
||||
if (languageNamedeta.value.id) {
|
||||
// 修改语言
|
||||
editLanguage(languageNamedeta.value)
|
||||
.then(() => {
|
||||
ElMessage({
|
||||
type: "success",
|
||||
message: "修改成功",
|
||||
});
|
||||
getLanguageListData();
|
||||
})
|
||||
.catch(() => {
|
||||
ElMessage({
|
||||
type: "error",
|
||||
message: "修改失败",
|
||||
});
|
||||
});
|
||||
dialogVisible.value = false;
|
||||
}else{
|
||||
// 新增语言
|
||||
addLanguage(languageNamedeta.value)
|
||||
.then(() => {
|
||||
ElMessage({
|
||||
type: "success",
|
||||
message: "添加成功",
|
||||
});
|
||||
getLanguageListData();
|
||||
})
|
||||
.catch(() => {
|
||||
ElMessage({
|
||||
type: "error",
|
||||
message: "添加失败",
|
||||
});
|
||||
});
|
||||
dialogVisible.value = false;
|
||||
}
|
||||
}
|
||||
// 删除语言
|
||||
function handleDelete(index, row) {
|
||||
ElMessageBox.confirm("您确认要删除这个语言吗?")
|
||||
.then(() => {
|
||||
deleteLanguage({ id: row.id })
|
||||
.then(() => {
|
||||
ElMessage({
|
||||
type: "success",
|
||||
message: "删除成功",
|
||||
});
|
||||
getLanguageListData();
|
||||
})
|
||||
.catch(() => {
|
||||
ElMessage({
|
||||
type: "error",
|
||||
message: "删除失败",
|
||||
});
|
||||
});
|
||||
})
|
||||
.catch(() => {});
|
||||
}
|
||||
|
||||
function getLanguageListData() {
|
||||
// 获取语言列表
|
||||
getLanguageList()
|
||||
.then((res) => {
|
||||
console.log(res);
|
||||
tableData.value = res;
|
||||
}).catch(() => {
|
||||
ElMessage({
|
||||
type: "error",
|
||||
message: "获取语言列表失败",
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
watch(refname, async (newQuestion, oldQuestion) => {
|
||||
// 变化后执行
|
||||
});
|
||||
onMounted(() => {
|
||||
getLanguageListData();
|
||||
// 组件挂载完成后执行
|
||||
});
|
||||
onUpdated(() => {
|
||||
// 组件更新后执行
|
||||
});
|
||||
onUnmounted(() => {
|
||||
// 组件销毁前执行
|
||||
});
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.language-management {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background-color: #ffffff;
|
||||
border-radius: 10px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
.content {
|
||||
width: 95%;
|
||||
height: 95%;
|
||||
background-color: #f5f5f5;
|
||||
border-radius: 10px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
box-shadow: 2px 4px 8px rgba(0, 0, 0, 0.3);
|
||||
}
|
||||
.languagetitle {
|
||||
width: 100%;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
height: 50px;
|
||||
background-color: #e2e2e2;
|
||||
border-radius: 10px;
|
||||
}
|
||||
.title {
|
||||
font-size: 24px;
|
||||
font-weight: bold;
|
||||
color: #999999;
|
||||
margin-left: 40px;
|
||||
}
|
||||
.add {
|
||||
width: 150px;
|
||||
height: 50px;
|
||||
background-color: #cccccc;
|
||||
border-radius: 10px;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
.add:hover {
|
||||
background-color: #999999;
|
||||
}
|
||||
.add-img {
|
||||
width: 40px;
|
||||
height: 40px;
|
||||
}
|
||||
.languagelist {
|
||||
width: 97%;
|
||||
height: 85%;
|
||||
background-color: #ffffff;
|
||||
margin-bottom: 20px;
|
||||
border-radius: 10px;
|
||||
overflow: auto;
|
||||
scrollbar-width: none;
|
||||
}
|
||||
.dialog-content {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
.dialog-title {
|
||||
width: 100%;
|
||||
height: 50px;
|
||||
font-size: 25px;
|
||||
color: #b4b4b4;
|
||||
font-weight: bold;
|
||||
margin-top: 20px;
|
||||
margin-bottom: 20px;
|
||||
text-align: center;
|
||||
}
|
||||
.dialog-btn {
|
||||
margin-top: 20px;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
}
|
||||
.dialogSave {
|
||||
width: 45%;
|
||||
height: 50px;
|
||||
background-color: #d6d6d6;
|
||||
line-height: 50px;
|
||||
text-align: center;
|
||||
font-weight: bold;
|
||||
border-radius: 5px;
|
||||
font-size: 16px;
|
||||
color: #ffffff;
|
||||
}
|
||||
.dialogSave:hover {
|
||||
background-color: #b4b4b4;
|
||||
}
|
||||
.dialogCancel {
|
||||
width: 45%;
|
||||
height: 50px;
|
||||
line-height: 50px;
|
||||
text-align: center;
|
||||
font-weight: bold;
|
||||
border-radius: 5px;
|
||||
font-size: 16px;
|
||||
color: #d6d6d6;
|
||||
border: 1px solid #d6d6d6;
|
||||
}
|
||||
.dialogCancel:hover {
|
||||
background-color: #e7e6e6;
|
||||
color: #ffffff;
|
||||
}
|
||||
</style>
|
||||
416
src/views/hosts/ai/scriptManagement.vue
Normal file
@@ -0,0 +1,416 @@
|
||||
<template>
|
||||
<div class="scriptManagement">
|
||||
<div class="wordslist">
|
||||
<!-- 话术列表 -->
|
||||
<div class="wordscontent" ref="containerRef">
|
||||
<div
|
||||
class="words"
|
||||
v-for="(item, index) in LanguageData"
|
||||
:key="index"
|
||||
:id="item.language"
|
||||
>
|
||||
<div class="wordsname">{{ item.language }}</div>
|
||||
<div class="wordscontents">
|
||||
<div
|
||||
class="wordscontentstext"
|
||||
v-for="(items, indexs) in item.content"
|
||||
:key="index"
|
||||
>
|
||||
<div>{{ indexs + 1 + ". " + items.content }}</div>
|
||||
<div class="wordscontentstextbtn">
|
||||
<div style="margin-right: 10px" @click="handleEditor(items.id)">编辑</div>
|
||||
<div @click="handleDelete(items.id)">删除</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="Languagelist">
|
||||
<div class="Languagecontent">
|
||||
<!-- 话术添加 -->
|
||||
<div class="addwords" @click="wordsAddStatus = true">
|
||||
<img class="addwordsimg" src="@/assets/plus.png" />
|
||||
</div>
|
||||
<!-- 语言选择 -->
|
||||
<el-anchor
|
||||
class="Languageanchor"
|
||||
:container="containerRef"
|
||||
direction="vertical"
|
||||
type="default"
|
||||
:offset="30"
|
||||
@click="handleClick"
|
||||
>
|
||||
<el-anchor-link
|
||||
class="anchorLink"
|
||||
v-for="(item, index) in getLanguageListData"
|
||||
:href="'#' + item.language"
|
||||
:title="item.language"
|
||||
:key="index"
|
||||
/>
|
||||
</el-anchor>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- 话术编辑 -->
|
||||
<el-drawer v-model="dialogVisible" :with-header="false">
|
||||
<div class="dialog-content">
|
||||
<div class="dialog-title">话术编辑</div>
|
||||
<el-input
|
||||
v-model="handletextareadeta.content"
|
||||
style="width: 100%; margin-top: 20px"
|
||||
:rows="25"
|
||||
type="textarea"
|
||||
placeholder="请输入话术内容"
|
||||
/>
|
||||
<div class="dialog-btn">
|
||||
<div class="dialogSave" @click="handleSave">保存</div>
|
||||
<div class="dialogCancel" @click="dialogVisible = false">取消</div>
|
||||
</div>
|
||||
</div>
|
||||
</el-drawer>
|
||||
<!-- 话术添加 -->
|
||||
<el-drawer v-model="wordsAddStatus" :with-header="false">
|
||||
<div class="dialog-content">
|
||||
<div class="dialog-title">话术编辑</div>
|
||||
<el-select v-model="wordsAddData.language" placeholder="请选择语言">
|
||||
<el-option
|
||||
v-for="item in LanguageData"
|
||||
:key="item.language"
|
||||
:label="item.language"
|
||||
:value="item.language"
|
||||
/>
|
||||
</el-select>
|
||||
<el-input
|
||||
v-model="wordsAddData.content"
|
||||
style="width: 100%; margin-top: 20px"
|
||||
:rows="25"
|
||||
type="textarea"
|
||||
placeholder="请输入话术内容"
|
||||
/>
|
||||
<div class="dialog-btn">
|
||||
<div class="dialogSave" @click="handleSaveWordsAdd">保存</div>
|
||||
<div class="dialogCancel" @click="wordsAddStatus = false">取消</div>
|
||||
</div>
|
||||
</div>
|
||||
</el-drawer>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import {
|
||||
getDialogList,
|
||||
getLanguageList,
|
||||
editDialog,
|
||||
deleteDialog,
|
||||
addDialog,
|
||||
} from "@/api/account";
|
||||
import { ElMessage, ElMessageBox } from "element-plus";
|
||||
import {
|
||||
ref, // 响应式基础
|
||||
watch, // 侦听器
|
||||
onMounted, // 组件挂载完成后执行
|
||||
onUpdated, // 组件更新后执行
|
||||
onUnmounted, // 组件销毁前执行
|
||||
} from "vue";
|
||||
const refname = ref("");
|
||||
const containerRef = ref(null);
|
||||
const getDialogListData = ref([]);
|
||||
const getLanguageListData = ref([]);
|
||||
const LanguageData = ref([]);
|
||||
const wordsAddStatus = ref(false);
|
||||
const wordsAddData = ref({
|
||||
language: "",
|
||||
content: "",
|
||||
});
|
||||
|
||||
const handleClick = (e) => {
|
||||
e.preventDefault();
|
||||
};
|
||||
|
||||
//数据处理
|
||||
function mergeArrays(arr1, arr2) {
|
||||
const result = [];
|
||||
const languages = new Set([...arr1.map(i => i.language), ...arr2.map(i => i.language)]);
|
||||
|
||||
for (const lang of languages) {
|
||||
const contents = arr1.filter(item => item.language === lang)
|
||||
.map(item => ({ id: item.id, content: item.content }));
|
||||
|
||||
result.push({
|
||||
language: lang,
|
||||
content: contents
|
||||
});
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
const dialogVisible = ref(false);
|
||||
const handletextareadeta = ref({});
|
||||
//添加话术
|
||||
function handleSaveWordsAdd() {
|
||||
console.log("handleSaveWordsAdd",wordsAddData.value);
|
||||
if (wordsAddData.value.language === "" || wordsAddData.value.content === "") {
|
||||
ElMessage({
|
||||
type: "error",
|
||||
message: "请填写完整信息",
|
||||
});
|
||||
return;
|
||||
}
|
||||
wordsAddStatus.value = false;
|
||||
addDialog(wordsAddData.value)
|
||||
.then(() => {
|
||||
ElMessage({
|
||||
type: "success",
|
||||
message: "添加成功",
|
||||
});
|
||||
getLanguageListDataFn();
|
||||
})
|
||||
.catch(() => {
|
||||
ElMessage({
|
||||
type: "error",
|
||||
message: "添加失败",
|
||||
});
|
||||
});
|
||||
}
|
||||
// 编辑
|
||||
function handleEditor(id) {
|
||||
dialogVisible.value = true;
|
||||
handletextareadeta.value = getDialogListData.value.find((item) => item.id === id);
|
||||
}
|
||||
|
||||
// 保存
|
||||
function handleSave() {
|
||||
editDialog({
|
||||
id: handletextareadeta.value.id,
|
||||
content: handletextareadeta.value.content,
|
||||
})
|
||||
.then(() => {
|
||||
ElMessage({
|
||||
type: "success",
|
||||
message: "保存成功",
|
||||
});
|
||||
getLanguageListDataFn();
|
||||
dialogVisible.value = false;
|
||||
})
|
||||
.catch(() => {
|
||||
ElMessage({
|
||||
type: "error",
|
||||
message: "保存失败",
|
||||
});
|
||||
});
|
||||
}
|
||||
// 删除
|
||||
function handleDelete(id) {
|
||||
ElMessageBox.confirm("您确认要删除这条话术吗?")
|
||||
.then(() => {
|
||||
deleteDialog({ id })
|
||||
.then(() => {
|
||||
ElMessage({
|
||||
type: "success",
|
||||
message: "删除成功",
|
||||
});
|
||||
getLanguageListDataFn();
|
||||
})
|
||||
.catch(() => {
|
||||
ElMessage({
|
||||
type: "error",
|
||||
message: "删除失败",
|
||||
});
|
||||
});
|
||||
})
|
||||
.catch(() => {});
|
||||
}
|
||||
function getLanguageListDataFn() {
|
||||
getDialogList().then((res) => {
|
||||
getDialogListData.value = res;
|
||||
getLanguageList().then((res) => {
|
||||
getLanguageListData.value = res;
|
||||
LanguageData.value = mergeArrays(
|
||||
getDialogListData.value,
|
||||
getLanguageListData.value
|
||||
);
|
||||
console.log("LanguageData", LanguageData.value);
|
||||
});
|
||||
});
|
||||
}
|
||||
watch(refname, async (newQuestion, oldQuestion) => {
|
||||
// 变化后执行
|
||||
});
|
||||
onMounted(() => {
|
||||
getLanguageListDataFn();
|
||||
});
|
||||
onUpdated(() => {
|
||||
// 组件更新后执行
|
||||
});
|
||||
onUnmounted(() => {
|
||||
// 组件销毁前执行
|
||||
});
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.scriptManagement {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background-color: #ffffff;
|
||||
border-radius: 10px;
|
||||
display: flex;
|
||||
}
|
||||
.wordslist {
|
||||
width: 87%;
|
||||
height: 97%;
|
||||
padding: 1% 1%;
|
||||
/* background-color: #00ff40; */
|
||||
}
|
||||
.Languagelist {
|
||||
height: 97%;
|
||||
width: 10%;
|
||||
padding: 1% 1% 1% 0%;
|
||||
/* background-color: #8d0000; */
|
||||
}
|
||||
.wordscontent {
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
border-radius: 10px;
|
||||
background-color: rgb(243, 243, 243);
|
||||
overflow-y: auto;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
scrollbar-width: none;
|
||||
}
|
||||
.Languagecontent {
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
border-radius: 10px;
|
||||
background-color: rgb(243, 243, 243);
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
overflow-y: auto;
|
||||
scrollbar-width: none; /* 隐藏滚动条 */
|
||||
}
|
||||
.addwords {
|
||||
width: 100%;
|
||||
height: 50px;
|
||||
background-color: rgb(226, 226, 226);
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
.addwords:hover {
|
||||
background-color: rgb(214, 214, 214);
|
||||
}
|
||||
.addwordsimg {
|
||||
width: 30px;
|
||||
height: 30px;
|
||||
}
|
||||
.Language {
|
||||
height: 50px;
|
||||
width: 100%;
|
||||
background-color: rgb(226, 226, 226);
|
||||
margin-top: 20px;
|
||||
}
|
||||
.words {
|
||||
width: 95%;
|
||||
margin-top: 20px;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
.Languageanchor {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
background-color: rgb(243, 243, 243);
|
||||
}
|
||||
.anchorLink {
|
||||
width: 100px;
|
||||
height: 30px;
|
||||
margin-top: 20px;
|
||||
margin-bottom: 20px;
|
||||
text-align: center;
|
||||
font-size: 16px;
|
||||
line-height: 30px;
|
||||
border-radius: 5px;
|
||||
margin-left: -0.875vw;
|
||||
}
|
||||
.wordsname {
|
||||
font-size: 18px;
|
||||
color: #c9c9c9;
|
||||
font-weight: bold;
|
||||
margin-top: 20px;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
.wordscontents {
|
||||
width: 95%;
|
||||
/* min-height: 200px; */
|
||||
/* background-color: #ffffff; */
|
||||
border-radius: 10px;
|
||||
margin-left: 30px;
|
||||
}
|
||||
.wordscontentstext {
|
||||
font-size: 16px;
|
||||
color: #7a7a7a;
|
||||
line-height: 24px;
|
||||
margin-top: 10px;
|
||||
margin-bottom: 10px;
|
||||
text-align: left;
|
||||
word-wrap: break-word;
|
||||
word-break: break-all;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
}
|
||||
.wordscontentstextbtn {
|
||||
display: flex;
|
||||
}
|
||||
.dialog-content {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
.dialog-title {
|
||||
width: 100%;
|
||||
height: 50px;
|
||||
font-size: 25px;
|
||||
color: #b4b4b4;
|
||||
font-weight: bold;
|
||||
margin-top: 20px;
|
||||
margin-bottom: 20px;
|
||||
text-align: center;
|
||||
}
|
||||
.dialog-btn {
|
||||
margin-top: 20px;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
}
|
||||
.dialogSave {
|
||||
width: 45%;
|
||||
height: 50px;
|
||||
background-color: #d6d6d6;
|
||||
line-height: 50px;
|
||||
text-align: center;
|
||||
font-weight: bold;
|
||||
border-radius: 5px;
|
||||
font-size: 16px;
|
||||
color: #ffffff;
|
||||
}
|
||||
.dialogSave:hover {
|
||||
background-color: #b4b4b4;
|
||||
}
|
||||
.dialogCancel {
|
||||
width: 45%;
|
||||
height: 50px;
|
||||
line-height: 50px;
|
||||
text-align: center;
|
||||
font-weight: bold;
|
||||
border-radius: 5px;
|
||||
font-size: 16px;
|
||||
color: #d6d6d6;
|
||||
border: 1px solid #d6d6d6;
|
||||
}
|
||||
.dialogCancel:hover {
|
||||
background-color: #e7e6e6;
|
||||
color: #ffffff;
|
||||
}
|
||||
/* 样式定义 */
|
||||
</style>
|
||||
47
src/views/hosts/mini/miniAM.vue
Normal file
@@ -0,0 +1,47 @@
|
||||
<template>
|
||||
<div class="miniAM">
|
||||
<div class="noData">
|
||||
暂无数据
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import {
|
||||
ref, // 响应式基础
|
||||
watch, // 侦听器
|
||||
onMounted, // 组件挂载完成后执行
|
||||
onUpdated, // 组件更新后执行
|
||||
onUnmounted, // 组件销毁前执行
|
||||
} from "vue";
|
||||
const refname = ref('');
|
||||
watch(refname, async (newQuestion, oldQuestion) => {
|
||||
// 变化后执行
|
||||
});
|
||||
onMounted(() => {
|
||||
// 组件挂载完成后执行
|
||||
});
|
||||
onUpdated(() => {
|
||||
// 组件更新后执行
|
||||
});
|
||||
onUnmounted(() => {
|
||||
// 组件销毁前执行
|
||||
});
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.miniAM {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background-color: #ffffff;
|
||||
border-radius: 10px;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
.noData{
|
||||
font-size: 20px;
|
||||
color: #999999;
|
||||
}
|
||||
/* 样式定义 */
|
||||
</style>
|
||||
315
src/views/hosts/mini/miniIntegral.vue
Normal file
@@ -0,0 +1,315 @@
|
||||
<template>
|
||||
<div class="mini-integral">
|
||||
<div class="content">
|
||||
<!-- 积分配置列表 -->
|
||||
<div class="integral-list">
|
||||
<el-table
|
||||
:data="tableData"
|
||||
stripe
|
||||
style="width: 100%; margin-top: 10px"
|
||||
max-height="700"
|
||||
>
|
||||
<el-table-column prop="functionName" label="事件" />
|
||||
<el-table-column prop="" label="" />
|
||||
<el-table-column prop="functionValue" label="积分" />
|
||||
<el-table-column prop="" label="" />
|
||||
<el-table-column label="操作">
|
||||
<template #default="scope">
|
||||
<el-button size="small" @click="miniIntegralEdit(scope.$index, scope.row)">
|
||||
修改
|
||||
</el-button>
|
||||
<el-button
|
||||
size="small"
|
||||
type="danger"
|
||||
@click="miniIntegralDelete(scope.$index, scope.row)"
|
||||
>
|
||||
删除
|
||||
</el-button>
|
||||
</template>
|
||||
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</div>
|
||||
<!-- 积分配置 -->
|
||||
<div class="integral-title">
|
||||
<div class="add" @click="dialogVisible = true">
|
||||
<img class="add-img" src="@/assets/plus2.png" alt="">
|
||||
</div>
|
||||
<div class="integral-text">
|
||||
<div class="h1">小</div>
|
||||
<div class="h1">程</div>
|
||||
<div class="h1">序</div>
|
||||
<div class="h1">积</div>
|
||||
<div class="h1">分</div>
|
||||
<div class="h1">配</div>
|
||||
<div class="h1">置</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 新增修改积分配置弹窗 -->
|
||||
<el-drawer v-model="dialogVisible" :with-header="false" @close="dialogVisible = false, miniIntegraldeta = {}">
|
||||
<div class="dialog-content">
|
||||
<div class="dialog-title">事件{{miniIntegraldeta.id? '编辑' : '新增'}}</div>
|
||||
<el-input
|
||||
v-if="!miniIntegraldeta.id"
|
||||
v-model="miniIntegraldeta.functionName"
|
||||
style="width: 100%; margin-top: 20px"
|
||||
:rows="3"
|
||||
type="textarea"
|
||||
placeholder="请输入事件名称"
|
||||
/>
|
||||
<el-input
|
||||
v-model="miniIntegraldeta.functionValue"
|
||||
style="width: 100%;height: 50px; margin-top: 20px"
|
||||
type="number"
|
||||
placeholder="请输入积分值"
|
||||
/>
|
||||
<div class="dialog-btn">
|
||||
<div class="dialogSave" @click="miniIntegralAddSave">保存</div>
|
||||
<div class="dialogCancel" @click="dialogVisible = false">取消</div>
|
||||
</div>
|
||||
</div>
|
||||
</el-drawer>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ElMessage, ElMessageBox } from "element-plus";
|
||||
import {
|
||||
getWxConfigList,
|
||||
addWxConfig,
|
||||
editWxConfig,
|
||||
deleteWxConfig,
|
||||
} from "@/api/account";
|
||||
import {
|
||||
ref, // 响应式基础
|
||||
watch, // 侦听器
|
||||
onMounted, // 组件挂载完成后执行
|
||||
onUpdated, // 组件更新后执行
|
||||
onUnmounted, // 组件销毁前执行
|
||||
} from "vue";
|
||||
const refname = ref("");
|
||||
const tableData = ref([]);
|
||||
const dialogVisible = ref(false);
|
||||
const miniIntegraldeta = ref({});
|
||||
//保存积分配置
|
||||
function miniIntegralAddSave() {
|
||||
if (!miniIntegraldeta.value.functionName) {
|
||||
ElMessage({
|
||||
type: "error",
|
||||
message: "事件名称不能为空",
|
||||
});
|
||||
return;
|
||||
}
|
||||
if (!miniIntegraldeta.value.functionValue) {
|
||||
ElMessage({
|
||||
type: "error",
|
||||
message: "积分值不能为空",
|
||||
});
|
||||
return;
|
||||
}
|
||||
if (miniIntegraldeta.value.id) {
|
||||
// 修改积分配置
|
||||
editWxConfig(miniIntegraldeta.value)
|
||||
.then(() => {
|
||||
ElMessage({
|
||||
type: "success",
|
||||
message: "修改成功",
|
||||
});
|
||||
dialogVisible.value = false;
|
||||
miniIntegraldeta.value = {};
|
||||
getIntegralList()
|
||||
})
|
||||
.catch(() => {
|
||||
ElMessage({
|
||||
type: "error",
|
||||
message: "修改失败",
|
||||
});
|
||||
});
|
||||
} else {
|
||||
// 新增积分配置
|
||||
addWxConfig(miniIntegraldeta.value)
|
||||
.then(() => {
|
||||
ElMessage({
|
||||
type: "success",
|
||||
message: "新增成功",
|
||||
});
|
||||
dialogVisible.value = false;
|
||||
miniIntegraldeta.value = {};
|
||||
getIntegralList()
|
||||
})
|
||||
.catch(() => {
|
||||
ElMessage({
|
||||
type: "error",
|
||||
message: "新增失败",
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
// 新增积分配置弹窗
|
||||
function miniIntegralEdit(index, row) {
|
||||
dialogVisible.value = true;
|
||||
miniIntegraldeta.value = row;
|
||||
}
|
||||
//删除积分配置
|
||||
function miniIntegralDelete(index, row) {
|
||||
ElMessageBox.confirm("您确认要删除这个积分配置吗?")
|
||||
.then(() => {
|
||||
deleteWxConfig({ id: row.id })
|
||||
.then(() => {
|
||||
ElMessage({
|
||||
type: "success",
|
||||
message: "删除成功",
|
||||
});
|
||||
getIntegralList()
|
||||
})
|
||||
.catch(() => {
|
||||
ElMessage({
|
||||
type: "error",
|
||||
message: "删除失败",
|
||||
});
|
||||
});
|
||||
})
|
||||
.catch(() => {});
|
||||
}
|
||||
// 获取积分配置列表
|
||||
function getIntegralList() {
|
||||
getWxConfigList()
|
||||
.then((res) => {
|
||||
tableData.value = res;
|
||||
})
|
||||
.catch(() => {
|
||||
ElMessage({
|
||||
type: "error",
|
||||
message: "获取积分配置列表失败",
|
||||
});
|
||||
});
|
||||
}
|
||||
watch(refname, async (newQuestion, oldQuestion) => {
|
||||
// 变化后执行
|
||||
});
|
||||
onMounted(() => {
|
||||
getIntegralList();
|
||||
});
|
||||
onUpdated(() => {
|
||||
// 组件更新后执行
|
||||
});
|
||||
onUnmounted(() => {
|
||||
// 组件销毁前执行
|
||||
});
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.mini-integral {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background-color: #ffffff;
|
||||
border-radius: 10px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
.content {
|
||||
width: 80%;
|
||||
height: 80%;
|
||||
background-color: #f5f5f5;
|
||||
border-radius: 10px;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
padding: 20px;
|
||||
box-shadow: 2px 4px 8px rgba(0, 0, 0, 0.3);
|
||||
padding: 40px;
|
||||
}
|
||||
.integral-list{
|
||||
width: 87%;
|
||||
height: 100%;
|
||||
background-color: #ffffff;
|
||||
border-radius: 10px;
|
||||
}
|
||||
.integral-title{
|
||||
width: 10%;
|
||||
height: 100%;
|
||||
background-color: #ffffff;
|
||||
border-radius: 10px;
|
||||
}
|
||||
.add{
|
||||
width: 100%;
|
||||
height: 50px;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
background-color: #c4c4c4;
|
||||
border-radius: 10px 10px 0 0;
|
||||
}
|
||||
.add:hover{
|
||||
background-color: #a9a9a9;
|
||||
}
|
||||
.add-img{
|
||||
width: 40px;
|
||||
height: 40px;
|
||||
}
|
||||
.integral-text{
|
||||
width: 100%;
|
||||
height: 520px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
font-size: 20px;
|
||||
color: #c4c4c4;
|
||||
font-size: 25px;
|
||||
font-family: "SimSun", "Microsoft YaHei", sans-serif;
|
||||
}
|
||||
.h1{
|
||||
margin-top: 10px;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
.dialog-title {
|
||||
width: 100%;
|
||||
height: 50px;
|
||||
font-size: 25px;
|
||||
color: #b4b4b4;
|
||||
font-weight: bold;
|
||||
margin-top: 20px;
|
||||
margin-bottom: 20px;
|
||||
text-align: center;
|
||||
}
|
||||
.dialog-btn {
|
||||
margin-top: 20px;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
}
|
||||
.dialogSave {
|
||||
width: 45%;
|
||||
height: 50px;
|
||||
background-color: #d6d6d6;
|
||||
line-height: 50px;
|
||||
text-align: center;
|
||||
font-weight: bold;
|
||||
border-radius: 5px;
|
||||
font-size: 16px;
|
||||
color: #ffffff;
|
||||
}
|
||||
.dialogSave:hover {
|
||||
background-color: #b4b4b4;
|
||||
}
|
||||
.dialogCancel {
|
||||
width: 45%;
|
||||
height: 50px;
|
||||
line-height: 50px;
|
||||
text-align: center;
|
||||
font-weight: bold;
|
||||
border-radius: 5px;
|
||||
font-size: 16px;
|
||||
color: #d6d6d6;
|
||||
border: 1px solid #d6d6d6;
|
||||
}
|
||||
.dialogCancel:hover {
|
||||
background-color: #e7e6e6;
|
||||
color: #ffffff;
|
||||
}
|
||||
/* 样式定义 */
|
||||
</style>
|
||||
@@ -3,13 +3,15 @@
|
||||
<div class="center-align" style="width: 100%; margin: 0 20px;">
|
||||
<div class="box-card-num1 center-line">
|
||||
<div>总数量: <span>{{ hostData.totalCount }}</span></div>
|
||||
<div>有效主播: <span>{{ hostData.validAnchorsCount }}</span></div>
|
||||
<div>新建主播: <span>{{ hostData.validAnchorsCount }}</span></div>
|
||||
<div> 已查询: <span>{{ hostData.checkedDataCount }}</span></div>
|
||||
<div>可邀请: <span>{{ hostData.canInvitationCount }}</span></div>
|
||||
<div>运行时间: <span>{{ formattedTime }}</span></div>
|
||||
|
||||
</div>
|
||||
<div class="center-line" style="padding-top: 15vh;">
|
||||
<el-button class="open-login" type="primary" @click="openTK">开启tk</el-button>
|
||||
<!-- <el-button class="open-login" type="primary" @click="startTimer">计时开始</el-button> -->
|
||||
</div>
|
||||
|
||||
<div>
|
||||
@@ -20,21 +22,21 @@
|
||||
<div class="from-input-item-title center-justify">
|
||||
公会账号:
|
||||
</div>
|
||||
<el-input :disabled="!(isTk && tkData[index].code == 0)" v-model="tkData[index].account"
|
||||
placeholder="请输入登录账号" clearable />
|
||||
<el-input :disabled="!(tkData[index].code == 0 && !isLogin[index])"
|
||||
v-model="tkData[index].account" placeholder="请输入登录账号" clearable />
|
||||
</div>
|
||||
|
||||
<div class="from-input-item">
|
||||
<div class="from-input-item-title center-justify">
|
||||
公会密码:
|
||||
</div>
|
||||
<el-input :disabled="!(isTk && tkData[index].code == 0)" v-model="tkData[index].password"
|
||||
type="password" placeholder="请输入登录密码" show-password />
|
||||
<el-input :disabled="!(tkData[index].code == 0 && !isLogin[index])"
|
||||
v-model="tkData[index].password" type="password" placeholder="请输入登录密码" show-password />
|
||||
</div>
|
||||
|
||||
<el-button class="open-login" style="margin-left: 60px;"
|
||||
:disabled="!(isTk && tkData[index].code == 0)" type="primary"
|
||||
@click="loginTK(index)">登录tk</el-button>
|
||||
:disabled="!(tkData[index].code == 0 && !isLogin[index])" type="primary"
|
||||
@click="loginTK(index)">登录后台</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>
|
||||
|
||||
@@ -86,14 +88,14 @@
|
||||
<el-col :span="8">
|
||||
<div class="input-group">
|
||||
<label>后台查询频率</label>
|
||||
<el-input type='number' v-model="pyData.frequency.hour" :min="0"
|
||||
:max="pyData.frequency.day - 1" placeholder="次/小时" style="width: 100%"
|
||||
:disabled="!pyData.isStart">
|
||||
<!-- <el-input type='number' v-model="pyData.frequency.hour" @input="handleInputHour" -->
|
||||
<el-input type='number' v-model="pyData.frequency.hour" placeholder="次/小时"
|
||||
style="width: 100%" :disabled="!pyData.isStart">
|
||||
<template #append>次/小时</template>
|
||||
</el-input>
|
||||
<el-input type='number' v-model="pyData.frequency.day" :min="pyData.frequency.hour + 1"
|
||||
:max="100" placeholder="次/24小时" style="width: 100%; margin-top: 10px"
|
||||
:disabled="!pyData.isStart">
|
||||
<!-- <el-input type='number' v-model="pyData.frequency.day" @input="handleInputDay" -->
|
||||
<el-input type='number' v-model="pyData.frequency.day" placeholder="次/24小时"
|
||||
style="width: 100%; margin-top: 10px" :disabled="!pyData.isStart">
|
||||
<template #append>次/24小时</template>
|
||||
</el-input>
|
||||
</div>
|
||||
@@ -113,12 +115,13 @@
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref, onMounted } from 'vue';
|
||||
import { ref, onMounted, computed } from 'vue';
|
||||
import { usePythonBridge, } from '@/utils/pythonBridge'
|
||||
import { setNumData, getNumData, getUser, setTkUser, getTkUser } from '@/utils/storage'
|
||||
import { ElMessage, ElMessageBox } from 'element-plus'
|
||||
import { getCountryName } from '@/utils/countryUtil'
|
||||
import { tkaccountuseinfo } from '@/api/account'
|
||||
|
||||
//导入python交互方法
|
||||
const { fetchDataConfig, fetchDataCount, loginBackStage, loginTikTok, backStageloginStatus, backStageloginStatusCopy } = usePythonBridge();
|
||||
|
||||
@@ -132,15 +135,27 @@ let hostData = ref({
|
||||
validAnchorsCount: 0,
|
||||
canInvitationCount: 0,
|
||||
checkedDataCount: 0,
|
||||
|
||||
});
|
||||
//是否开启tk
|
||||
let isTk = ref(true);
|
||||
// let isTk = ref(true);
|
||||
|
||||
//账号是否登陆中
|
||||
let isLogin = ref([false, false]);
|
||||
//设置状态轮询定时器
|
||||
let statusTimer = ref(null);
|
||||
let statusTimerCopy = ref(null);
|
||||
|
||||
//设置次数最大值
|
||||
let maxCount = ref([
|
||||
{
|
||||
hourMax: 50,
|
||||
dayMax: 300,
|
||||
},
|
||||
{
|
||||
hourMax: 100,
|
||||
dayMax: 600,
|
||||
},
|
||||
]);
|
||||
|
||||
//tk账号信息
|
||||
let tkData = ref([
|
||||
@@ -157,9 +172,7 @@ let tkData = ref([
|
||||
index: 2,
|
||||
code: 0,
|
||||
num: 0
|
||||
|
||||
},
|
||||
|
||||
]);
|
||||
|
||||
//python需要的数据
|
||||
@@ -176,7 +189,8 @@ let pyData = ref({
|
||||
});
|
||||
|
||||
//按钮提交状态
|
||||
let submitting = ref(false);
|
||||
let submitting = ref(true);
|
||||
|
||||
|
||||
onMounted(() => {
|
||||
//从缓存获取数据
|
||||
@@ -193,7 +207,6 @@ onMounted(() => {
|
||||
tkaccountuse(tkData.value[1].account, 1)
|
||||
|
||||
getIpInfo()
|
||||
//查询次数查询
|
||||
|
||||
|
||||
})
|
||||
@@ -210,6 +223,22 @@ const getIpInfo = async () => {
|
||||
countryData.value = getCountryName(data.country);
|
||||
} catch (error) {
|
||||
console.error('请求出错:', error);
|
||||
ElMessageBox.prompt('请输入将要获取国家的中文名', '获取国家失败', {
|
||||
confirmButtonText: '确认',
|
||||
cancelButtonText: '取消',
|
||||
showClose: false,
|
||||
closeOnClickModal: false,
|
||||
showCancelButton: false,
|
||||
})
|
||||
.then(({ value }) => {
|
||||
countryData.value = value
|
||||
})
|
||||
// .catch(() => {
|
||||
// ElMessage({
|
||||
// type: 'info',
|
||||
// message: 'Input canceled',
|
||||
// })
|
||||
// })
|
||||
}
|
||||
};
|
||||
|
||||
@@ -217,12 +246,26 @@ const getIpInfo = async () => {
|
||||
const submit = () => {
|
||||
pyData.value.country = countryData.value;
|
||||
console.log('提交的区间值:', pyData.value);
|
||||
if (tkData.value[0].account == '' || tkData.value[1].account == '') {
|
||||
ElMessage.error('请输入账号密码');
|
||||
// if (tkData.value[0].account == '' && tkData.value[1].account == '') {
|
||||
// ElMessage.error('请输入账号密码');
|
||||
// return;
|
||||
// }
|
||||
// if (tkData.value[0].password == '' && tkData.value[1].password == '') {
|
||||
// ElMessage.error('请输入账号密码');
|
||||
// return;
|
||||
// }
|
||||
|
||||
|
||||
if (((Number(pyData.value.gold.min) > Number(pyData.value.gold.max)) || (Number(pyData.value.fans.min) > Number(pyData.value.fans.max)))) {
|
||||
ElMessage.error('请输入正确的区间值');
|
||||
return;
|
||||
}
|
||||
if (tkData.value[0].password == '' || tkData.value[1].password == '') {
|
||||
ElMessage.error('请输入账号密码');
|
||||
if ((Number(pyData.value.gold.max) <= 0 || Number(pyData.value.fans.max <= 0)) || pyData.value.gold.max == '' || pyData.value.fans.max == '') {
|
||||
ElMessage.error('请输入正确的区间值');
|
||||
return;
|
||||
}
|
||||
if (Number(pyData.value.frequency.hour) <= 0 || Number(pyData.value.frequency.day) <= 0 || pyData.value.frequency.hour == '' || pyData.value.frequency.day == '') {
|
||||
ElMessage.error('请输入正确的频率区间值');
|
||||
return;
|
||||
}
|
||||
ElMessageBox.confirm(
|
||||
@@ -250,14 +293,16 @@ const submit = () => {
|
||||
tenantId: getUser().tenantId,
|
||||
userId: getUser().userId,
|
||||
})).then((res) => {
|
||||
|
||||
//开始计时器
|
||||
startTimer();
|
||||
//开启查询次数
|
||||
getHostTimer.value = setInterval(() => {
|
||||
fetchDataCount().then((res) => {
|
||||
hostData.value = JSON.parse(res);
|
||||
tkaccountuse(tkData.value[0].account, 0)
|
||||
tkaccountuse(tkData.value[1].account, 1)
|
||||
})
|
||||
}, 1000);
|
||||
}, 5000);
|
||||
|
||||
|
||||
}).finally(() => {
|
||||
@@ -287,6 +332,7 @@ const unsubmit = () => {
|
||||
tenantId: getUser().tenantId,
|
||||
userId: getUser().userId,
|
||||
})).then((res) => {
|
||||
pauseTimer();
|
||||
pyData.value.isStart = true;
|
||||
clearInterval(getHostTimer.value);
|
||||
getHostTimer.value = null;
|
||||
@@ -312,10 +358,12 @@ const loginTK = (index) => {
|
||||
index: index
|
||||
})
|
||||
if (index == 0) {
|
||||
isLogin.value[1] = true;
|
||||
statusTimer = setInterval(() => {
|
||||
getloginStatus();
|
||||
}, 2000)
|
||||
} else if (index == 1) {
|
||||
isLogin.value[0] = true;
|
||||
statusTimerCopy = setInterval(() => {
|
||||
getloginStatusCopy();
|
||||
}, 2000)
|
||||
@@ -325,8 +373,8 @@ const loginTK = (index) => {
|
||||
}
|
||||
|
||||
const openTK = () => {
|
||||
isTk.value = true;
|
||||
console.log(isTk.value)
|
||||
// isTk.value = true;
|
||||
// console.log(isTk.value)
|
||||
loginTikTok();
|
||||
|
||||
}
|
||||
@@ -339,6 +387,8 @@ function getloginStatus() {
|
||||
if (data.code == 1) {
|
||||
clearInterval(statusTimer);
|
||||
statusTimer = null;
|
||||
submitting.value = false
|
||||
isLogin.value[1] = false;
|
||||
}
|
||||
})
|
||||
}
|
||||
@@ -350,6 +400,8 @@ function getloginStatusCopy() {
|
||||
if (data.code == 1) {
|
||||
clearInterval(statusTimer);
|
||||
statusTimer = null;
|
||||
submitting.value = false
|
||||
isLogin.value[0] = false;
|
||||
}
|
||||
})
|
||||
}
|
||||
@@ -357,13 +409,114 @@ function getloginStatusCopy() {
|
||||
|
||||
function tkaccountuse(id, index) {
|
||||
let num = 0;
|
||||
tkaccountuseinfo({ userId: id }).then((res) => {
|
||||
num = res
|
||||
tkData.value[index].num = num
|
||||
console.log('账号使用次数', tkData.value[index].num)
|
||||
tkaccountuseinfo(id).then((res) => {
|
||||
if (res) {
|
||||
num = res
|
||||
tkData.value[index].num = num
|
||||
console.log('账号使用次数', tkData.value[index].num)
|
||||
}
|
||||
}).catch((err) => {
|
||||
console.log('账号使用次数', err)
|
||||
})
|
||||
|
||||
}
|
||||
|
||||
const isRunning = ref(false);
|
||||
const totalSeconds = ref(0);
|
||||
//定时器
|
||||
let timerCrawl = null;
|
||||
|
||||
const startTimedata = ref(null);
|
||||
//清空时间 并开始运行
|
||||
const startTimer = () => {
|
||||
resetTimer();
|
||||
if (isRunning.value) return;
|
||||
isRunning.value = true;
|
||||
startTimedata.value = Date.now();
|
||||
timerCrawl = setInterval(() => {
|
||||
totalSeconds.value = Math.floor((Date.now() - startTimedata.value) / 1000);
|
||||
}, 1000);
|
||||
};
|
||||
|
||||
//结束运行 暂停
|
||||
const pauseTimer = () => {
|
||||
isRunning.value = false;
|
||||
clearInterval(timerCrawl);
|
||||
};
|
||||
//清空时间
|
||||
const resetTimer = () => {
|
||||
isRunning.value = false;
|
||||
clearInterval(timerCrawl);
|
||||
totalSeconds.value = 0;
|
||||
};
|
||||
// 格式化时间为 HH:MM:SS
|
||||
const formattedTime = computed(() => {
|
||||
const hours = Math.floor(totalSeconds.value / 3600);
|
||||
const minutes = Math.floor((totalSeconds.value % 3600) / 60);
|
||||
const seconds = totalSeconds.value % 60;
|
||||
|
||||
return [
|
||||
hours.toString().padStart(2, '0'),
|
||||
minutes.toString().padStart(2, '0'),
|
||||
seconds.toString().padStart(2, '0')
|
||||
].join(':');
|
||||
});
|
||||
|
||||
|
||||
function handleInputHour(value) {
|
||||
console.log(value)
|
||||
// 替换非数字字符为空字符串
|
||||
let num = value.replace(/[^\d]/g, '');
|
||||
// 如果值小于等于0,则设置为0
|
||||
if (Number(num) <= 0) {
|
||||
num = 0;
|
||||
}
|
||||
|
||||
if ((tkData.value[0].code == 1) && (tkData.value[1].code == 1)) {
|
||||
if (Number(num) > maxCount.value[1].hourMax) {
|
||||
num = maxCount.value[1].hourMax;
|
||||
}
|
||||
} else if ((tkData.value[0].code == 1) || (tkData.value[1].code == 1)) {
|
||||
// 如果值大于最大值,则设置为最大值
|
||||
if (Number(num) > maxCount.value[0].hourMax) {
|
||||
num = maxCount.value[0].hourMax;
|
||||
}
|
||||
|
||||
} else {
|
||||
ElMessage.error('请先登录tk后台');
|
||||
num = 0;
|
||||
}
|
||||
// 更新模型
|
||||
pyData.value.frequency.hour = num;
|
||||
}
|
||||
|
||||
function handleInputDay(value) {
|
||||
console.log(value)
|
||||
// 替换非数字字符为空字符串
|
||||
let num = value.replace(/[^\d]/g, '');
|
||||
// 如果值小于等于0,则设置为0
|
||||
if (Number(num) <= 0) {
|
||||
num = 0;
|
||||
}
|
||||
|
||||
if ((tkData.value[0].code == 1) && (tkData.value[1].code == 1)) {
|
||||
if (Number(num) > maxCount.value[1].dayMax) {
|
||||
num = maxCount.value[1].dayMax;
|
||||
}
|
||||
} else if ((tkData.value[0].code == 1) || (tkData.value[1].code == 1)) {
|
||||
// 如果值大于最大值,则设置为最大值
|
||||
if (Number(num) > maxCount.value[0].dayMax) {
|
||||
num = maxCount.value[0].dayMax;
|
||||
}
|
||||
} else {
|
||||
ElMessage.error('请先登录tk后台');
|
||||
num = 0;
|
||||
}
|
||||
|
||||
|
||||
// 更新模型
|
||||
pyData.value.frequency.day = num;
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped lang="less">
|
||||
@@ -398,7 +551,7 @@ function tkaccountuse(id, index) {
|
||||
background: #FFFFFF;
|
||||
box-shadow: 0px 0px 21px 0px rgba(183, 183, 183, 0.33);
|
||||
border-radius: 24px;
|
||||
padding-top: 60px;
|
||||
// padding-top: 60px;
|
||||
box-sizing: border-box;
|
||||
|
||||
div {
|
||||
@@ -498,7 +651,7 @@ label {
|
||||
.open-login {
|
||||
width: 100px;
|
||||
height: 47px;
|
||||
background: #E7CA92;
|
||||
background: @btn-bg-color;
|
||||
border-radius: 10px;
|
||||
border: none;
|
||||
}
|
||||
@@ -506,7 +659,7 @@ label {
|
||||
.reset-button {
|
||||
width: 132px;
|
||||
height: 47px;
|
||||
background: #E7CA92;
|
||||
background: @btn-bg-color;
|
||||
border-radius: 10px;
|
||||
|
||||
font-family: Source Han Sans SC;
|
||||
@@ -520,7 +673,7 @@ label {
|
||||
.submit-button {
|
||||
width: 160px;
|
||||
height: 47px;
|
||||
background: #338F6A;
|
||||
background: @bg-color;
|
||||
border-radius: 10px;
|
||||
}
|
||||
|
||||
@@ -551,9 +704,9 @@ label {
|
||||
</style>
|
||||
|
||||
|
||||
<style scoped>
|
||||
<style scoped lang="less">
|
||||
::v-deep(.el-input-group__prepend) {
|
||||
background: #84CEB2;
|
||||
background: @bg-color-light;
|
||||
border-radius: 10px 0px 0px 10px;
|
||||
border: 1px solid #B7CEC5;
|
||||
font-family: Source Han Sans SC;
|
||||
@@ -564,7 +717,7 @@ label {
|
||||
}
|
||||
|
||||
::v-deep(.el-input-group__append) {
|
||||
background: #84CEB2;
|
||||
background: @bg-color-light;
|
||||
border-radius: 0px 10px 10px 0px;
|
||||
border: 1px solid #B7CEC5;
|
||||
font-family: Source Han Sans SC;
|
||||
|
||||
@@ -1,58 +1,79 @@
|
||||
<template>
|
||||
<div class="app-container">
|
||||
<Sidebar class="noneText" @activeIndex="activeIndexFn" />
|
||||
<!-- <Sidebar class="noneText" @activeIndex="activeIndexFn" /> -->
|
||||
<div class="content ">
|
||||
<div v-show="activeIndex == 1">
|
||||
<workbenches v-if="openWerk" />
|
||||
<!-- <div v-show="activeIndexA == 1">
|
||||
<workbenches />
|
||||
</div> -->
|
||||
<div>
|
||||
<hostsList />
|
||||
</div>
|
||||
<div v-show="activeIndex == 2">
|
||||
<hostsList v-if="openList" />
|
||||
</div>
|
||||
|
||||
|
||||
<!-- <div style="position: absolute; bottom: 0; right: 0;">{{ version }}</div> -->
|
||||
</div>
|
||||
<div class="footer">
|
||||
{{ $t('common.expirationtime') }}{{ time }}
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import Sidebar from '../components/Sidebar.vue';
|
||||
import { useI18n } from 'vue-i18n';
|
||||
import { ref, reactive, onMounted } from "vue";
|
||||
// import Sidebar from '../components/Sidebar.vue';
|
||||
import { RouterLink, RouterView } from 'vue-router'
|
||||
import hostsList from '@/views/hosts/hostsList.vue'
|
||||
import workbenches from '@/views/hosts/workbenches.vue'
|
||||
import { ref } from 'vue'
|
||||
import { getUser } from '@/utils/storage'
|
||||
|
||||
let userType = ref(getUser().userType)
|
||||
let activeIndex = ref(userType.value == 3 ? 1 : 2)
|
||||
let openWerk = ref(userType.value == 3 ? true : false)
|
||||
let openList = ref(userType.value == 3 ? false : true)
|
||||
console.log("用户等级", getUser().userType)
|
||||
|
||||
|
||||
|
||||
function activeIndexFn(data) {
|
||||
activeIndex.value = data
|
||||
openWerk.value = true
|
||||
openList.value = true
|
||||
console.log(data)
|
||||
import { ElMessage } from 'element-plus';
|
||||
import { getUser } from "@/utils/storage";
|
||||
// import workbenches from '@/views/hosts/workbenches.vue'
|
||||
import { tokenStore,UserStore } from '@/stores/notice'
|
||||
const userCache = UserStore()
|
||||
const { t } = useI18n();
|
||||
const time = ref(formatTimestamp(userCache.user.brotherExpireTime))
|
||||
// 时间格式化方法 - 将12位时间戳转为YYYY-MM-DD HH:mm:ss格式
|
||||
function formatTimestamp(timestamp) {
|
||||
try {
|
||||
// 转换为数字
|
||||
const ts = Number(timestamp);
|
||||
if (isNaN(ts)) {
|
||||
return '--';
|
||||
}
|
||||
// 处理13位时间戳(毫秒级)
|
||||
const date = new Date(ts > 999999999999 ? ts : ts * 1000);
|
||||
const year = date.getFullYear();
|
||||
const month = String(date.getMonth() + 1).padStart(2, '0');
|
||||
const day = String(date.getDate()).padStart(2, '0');
|
||||
const hours = String(date.getHours()).padStart(2, '0');
|
||||
const minutes = String(date.getMinutes()).padStart(2, '0');
|
||||
const seconds = String(date.getSeconds()).padStart(2, '0');
|
||||
return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`;
|
||||
} catch (e) {
|
||||
console.error('时间格式化错误:', e);
|
||||
return '--';
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
</script>
|
||||
|
||||
<style>
|
||||
<style lang="less">
|
||||
body,
|
||||
html {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
height: 100%;
|
||||
/* 页面无法选中 */
|
||||
-webkit-user-select: none;
|
||||
-moz-user-select: none;
|
||||
-ms-user-select: none;
|
||||
user-select: none;
|
||||
}
|
||||
|
||||
.app-container {
|
||||
display: flex;
|
||||
width: 1600px;
|
||||
height: 900px;
|
||||
background-color: #338F6A;
|
||||
background-color: @bg-color;
|
||||
position: relative;
|
||||
|
||||
|
||||
}
|
||||
@@ -67,15 +88,17 @@ html {
|
||||
|
||||
.sidebar {
|
||||
width: 200px;
|
||||
background-color: #338F6A;
|
||||
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;
|
||||
// margin-left: 280px;
|
||||
margin-left: 25px;
|
||||
margin-right: 25px;
|
||||
width: 1540px;
|
||||
height: 848px;
|
||||
background: #FFFFFF;
|
||||
border-radius: 36px;
|
||||
margin-top: 16px;
|
||||
@@ -86,4 +109,11 @@ html {
|
||||
justify-content: space-around;
|
||||
align-items: center;
|
||||
}
|
||||
.footer{
|
||||
position: absolute;
|
||||
bottom: 10px;
|
||||
left: calc(50% - 150px);
|
||||
color: aqua;
|
||||
font-size: 16px;
|
||||
}
|
||||
</style>
|
||||
BIN
tk-page.rar
@@ -18,6 +18,9 @@ module.exports = defineConfig({
|
||||
})
|
||||
]
|
||||
}
|
||||
},
|
||||
less: {
|
||||
additionalData: `@import "@/static/css/app.less";` // 注入全局变量文件
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||