Compare commits
100 Commits
master
...
feature-ci
| Author | SHA1 | Date |
|---|---|---|
|
|
609d97ddbd | |
|
|
8121c1ce7c | |
|
|
9843b925dd | |
|
|
2a49524615 | |
|
|
476b51edbb | |
|
|
3fafc002e3 | |
|
|
d0180115bf | |
|
|
1705d6d763 | |
|
|
dc76811e15 | |
|
|
3c22de6e2f | |
|
|
0da522c90b | |
|
|
318ecc2578 | |
|
|
7ebe4a0952 | |
|
|
f13aabd082 | |
|
|
513faea916 | |
|
|
b5073c1948 | |
|
|
8c4f04d821 | |
|
|
296ba34b38 | |
|
|
1e54834c15 | |
|
|
759b24fe43 | |
|
|
7a24b3efc2 | |
|
|
0bf5f0a1d4 | |
|
|
7cf85e8bdb | |
|
|
2a477d18ca | |
|
|
42fabb0179 | |
|
|
138c26add1 | |
|
|
4d568bbc0b | |
|
|
a14f8a8d93 | |
|
|
9ed8f050e3 | |
|
|
6b0ec18722 | |
|
|
7f3a258ebd | |
|
|
f7c690bad7 | |
|
|
e2ebe67184 | |
|
|
747e1d1895 | |
|
|
3d5acbe68a | |
|
|
271ecb19ab | |
|
|
d1ea903c7b | |
|
|
8eb0daa25a | |
|
|
400a40cb9c | |
|
|
cf042ea5d1 | |
|
|
52a8d03bf4 | |
|
|
cf0577f70c | |
|
|
d6264ad44e | |
|
|
cfe1eb8f3b | |
|
|
be0a4a0a74 | |
|
|
2dfd5ac7ae | |
|
|
06037f56ad | |
|
|
3b874137d7 | |
|
|
ce1bd569a3 | |
|
|
d3296797ce | |
|
|
fa50b581e0 | |
|
|
6da564fcea | |
|
|
4927c5a710 | |
|
|
132fa10ce4 | |
|
|
e06dfcb0fe | |
|
|
e41b5ef5ff | |
|
|
3f16b7a0b8 | |
|
|
0b35eb17af | |
|
|
6036a772fd | |
|
|
afaea81a31 | |
|
|
cc424f3062 | |
|
|
3597c23525 | |
|
|
2083456ca5 | |
|
|
d6aa73cba4 | |
|
|
4ad46ac69d | |
|
|
50595df30a | |
|
|
0471fd0169 | |
|
|
9f6251ff1a | |
|
|
7ec0490577 | |
|
|
108c590d95 | |
|
|
4c976c5a34 | |
|
|
651b1afb3b | |
|
|
ee77bbf130 | |
|
|
6511b431ae | |
|
|
9336042b3b | |
|
|
07cee69631 | |
|
|
4f55a5070a | |
|
|
120e5c6167 | |
|
|
647afd9e94 | |
|
|
08f559c80e | |
|
|
782b831334 | |
|
|
4f735d82f7 | |
|
|
b795f89b86 | |
|
|
8a306bdee2 | |
|
|
a4d11ecf9e | |
|
|
9257458d85 | |
|
|
4802a22196 | |
|
|
a3f524e345 | |
|
|
260bd5a5d9 | |
|
|
3c22ca29a8 | |
|
|
ea4a1b7773 | |
|
|
0741f83a0f | |
|
|
776a5f64e7 | |
|
|
19c671de8b | |
|
|
2f68ef1f1d | |
|
|
b98d3313f5 | |
|
|
2ac513bda8 | |
|
|
1c9a259ca2 | |
|
|
ba268f1422 | |
|
|
955e379333 |
|
|
@ -12,9 +12,13 @@
|
|||
"cors": "^2.8.5",
|
||||
"crypto-js": "^4.2.0",
|
||||
"element-plus": "^2.4.4",
|
||||
"highlight.js": "^11.11.1",
|
||||
"js-cookie": "^3.0.5",
|
||||
"js-md5": "^0.8.3",
|
||||
"markdown-it": "^14.1.0",
|
||||
"qrcode": "^1.5.3",
|
||||
"spark-md5": "^3.0.2",
|
||||
"video_ca": "file:",
|
||||
"video.js": "^8.9.0",
|
||||
"vue": "^3.3.11",
|
||||
"vue-cookies": "^1.8.3",
|
||||
|
|
@ -66,9 +70,9 @@
|
|||
}
|
||||
},
|
||||
"node_modules/@esbuild/aix-ppc64": {
|
||||
"version": "0.19.11",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.19.11.tgz",
|
||||
"integrity": "sha512-FnzU0LyE3ySQk7UntJO4+qIiQgI7KoODnZg5xzXIrFJlKd2P2gwHsHY4927xj9y5PJmJSzULiUCWmv7iWnNa7g==",
|
||||
"version": "0.21.5",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.21.5.tgz",
|
||||
"integrity": "sha512-1SDgH6ZSPTlggy1yI6+Dbkiz8xzpHJEVAlF/AM1tHPLsf5STom9rwtjE4hKAF20FfXXNTFqEYXyJNWh1GiZedQ==",
|
||||
"cpu": [
|
||||
"ppc64"
|
||||
],
|
||||
|
|
@ -82,9 +86,9 @@
|
|||
}
|
||||
},
|
||||
"node_modules/@esbuild/android-arm": {
|
||||
"version": "0.19.11",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.19.11.tgz",
|
||||
"integrity": "sha512-5OVapq0ClabvKvQ58Bws8+wkLCV+Rxg7tUVbo9xu034Nm536QTII4YzhaFriQ7rMrorfnFKUsArD2lqKbFY4vw==",
|
||||
"version": "0.21.5",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.21.5.tgz",
|
||||
"integrity": "sha512-vCPvzSjpPHEi1siZdlvAlsPxXl7WbOVUBBAowWug4rJHb68Ox8KualB+1ocNvT5fjv6wpkX6o/iEpbDrf68zcg==",
|
||||
"cpu": [
|
||||
"arm"
|
||||
],
|
||||
|
|
@ -98,9 +102,9 @@
|
|||
}
|
||||
},
|
||||
"node_modules/@esbuild/android-arm64": {
|
||||
"version": "0.19.11",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.19.11.tgz",
|
||||
"integrity": "sha512-aiu7K/5JnLj//KOnOfEZ0D90obUkRzDMyqd/wNAUQ34m4YUPVhRZpnqKV9uqDGxT7cToSDnIHsGooyIczu9T+Q==",
|
||||
"version": "0.21.5",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.21.5.tgz",
|
||||
"integrity": "sha512-c0uX9VAUBQ7dTDCjq+wdyGLowMdtR/GoC2U5IYk/7D1H1JYC0qseD7+11iMP2mRLN9RcCMRcjC4YMclCzGwS/A==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
|
|
@ -114,9 +118,9 @@
|
|||
}
|
||||
},
|
||||
"node_modules/@esbuild/android-x64": {
|
||||
"version": "0.19.11",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.19.11.tgz",
|
||||
"integrity": "sha512-eccxjlfGw43WYoY9QgB82SgGgDbibcqyDTlk3l3C0jOVHKxrjdc9CTwDUQd0vkvYg5um0OH+GpxYvp39r+IPOg==",
|
||||
"version": "0.21.5",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.21.5.tgz",
|
||||
"integrity": "sha512-D7aPRUUNHRBwHxzxRvp856rjUHRFW1SdQATKXH2hqA0kAZb1hKmi02OpYRacl0TxIGz/ZmXWlbZgjwWYaCakTA==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
|
|
@ -130,9 +134,9 @@
|
|||
}
|
||||
},
|
||||
"node_modules/@esbuild/darwin-arm64": {
|
||||
"version": "0.19.11",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.19.11.tgz",
|
||||
"integrity": "sha512-ETp87DRWuSt9KdDVkqSoKoLFHYTrkyz2+65fj9nfXsaV3bMhTCjtQfw3y+um88vGRKRiF7erPrh/ZuIdLUIVxQ==",
|
||||
"version": "0.21.5",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.21.5.tgz",
|
||||
"integrity": "sha512-DwqXqZyuk5AiWWf3UfLiRDJ5EDd49zg6O9wclZ7kUMv2WRFr4HKjXp/5t8JZ11QbQfUS6/cRCKGwYhtNAY88kQ==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
|
|
@ -146,9 +150,9 @@
|
|||
}
|
||||
},
|
||||
"node_modules/@esbuild/darwin-x64": {
|
||||
"version": "0.19.11",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.19.11.tgz",
|
||||
"integrity": "sha512-fkFUiS6IUK9WYUO/+22omwetaSNl5/A8giXvQlcinLIjVkxwTLSktbF5f/kJMftM2MJp9+fXqZ5ezS7+SALp4g==",
|
||||
"version": "0.21.5",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.21.5.tgz",
|
||||
"integrity": "sha512-se/JjF8NlmKVG4kNIuyWMV/22ZaerB+qaSi5MdrXtd6R08kvs2qCN4C09miupktDitvh8jRFflwGFBQcxZRjbw==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
|
|
@ -162,9 +166,9 @@
|
|||
}
|
||||
},
|
||||
"node_modules/@esbuild/freebsd-arm64": {
|
||||
"version": "0.19.11",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.19.11.tgz",
|
||||
"integrity": "sha512-lhoSp5K6bxKRNdXUtHoNc5HhbXVCS8V0iZmDvyWvYq9S5WSfTIHU2UGjcGt7UeS6iEYp9eeymIl5mJBn0yiuxA==",
|
||||
"version": "0.21.5",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.21.5.tgz",
|
||||
"integrity": "sha512-5JcRxxRDUJLX8JXp/wcBCy3pENnCgBR9bN6JsY4OmhfUtIHe3ZW0mawA7+RDAcMLrMIZaf03NlQiX9DGyB8h4g==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
|
|
@ -178,9 +182,9 @@
|
|||
}
|
||||
},
|
||||
"node_modules/@esbuild/freebsd-x64": {
|
||||
"version": "0.19.11",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.19.11.tgz",
|
||||
"integrity": "sha512-JkUqn44AffGXitVI6/AbQdoYAq0TEullFdqcMY/PCUZ36xJ9ZJRtQabzMA+Vi7r78+25ZIBosLTOKnUXBSi1Kw==",
|
||||
"version": "0.21.5",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.21.5.tgz",
|
||||
"integrity": "sha512-J95kNBj1zkbMXtHVH29bBriQygMXqoVQOQYA+ISs0/2l3T9/kj42ow2mpqerRBxDJnmkUDCaQT/dfNXWX/ZZCQ==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
|
|
@ -194,9 +198,9 @@
|
|||
}
|
||||
},
|
||||
"node_modules/@esbuild/linux-arm": {
|
||||
"version": "0.19.11",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.19.11.tgz",
|
||||
"integrity": "sha512-3CRkr9+vCV2XJbjwgzjPtO8T0SZUmRZla+UL1jw+XqHZPkPgZiyWvbDvl9rqAN8Zl7qJF0O/9ycMtjU67HN9/Q==",
|
||||
"version": "0.21.5",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.21.5.tgz",
|
||||
"integrity": "sha512-bPb5AHZtbeNGjCKVZ9UGqGwo8EUu4cLq68E95A53KlxAPRmUyYv2D6F0uUI65XisGOL1hBP5mTronbgo+0bFcA==",
|
||||
"cpu": [
|
||||
"arm"
|
||||
],
|
||||
|
|
@ -210,9 +214,9 @@
|
|||
}
|
||||
},
|
||||
"node_modules/@esbuild/linux-arm64": {
|
||||
"version": "0.19.11",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.19.11.tgz",
|
||||
"integrity": "sha512-LneLg3ypEeveBSMuoa0kwMpCGmpu8XQUh+mL8XXwoYZ6Be2qBnVtcDI5azSvh7vioMDhoJFZzp9GWp9IWpYoUg==",
|
||||
"version": "0.21.5",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.21.5.tgz",
|
||||
"integrity": "sha512-ibKvmyYzKsBeX8d8I7MH/TMfWDXBF3db4qM6sy+7re0YXya+K1cem3on9XgdT2EQGMu4hQyZhan7TeQ8XkGp4Q==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
|
|
@ -226,9 +230,9 @@
|
|||
}
|
||||
},
|
||||
"node_modules/@esbuild/linux-ia32": {
|
||||
"version": "0.19.11",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.19.11.tgz",
|
||||
"integrity": "sha512-caHy++CsD8Bgq2V5CodbJjFPEiDPq8JJmBdeyZ8GWVQMjRD0sU548nNdwPNvKjVpamYYVL40AORekgfIubwHoA==",
|
||||
"version": "0.21.5",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.21.5.tgz",
|
||||
"integrity": "sha512-YvjXDqLRqPDl2dvRODYmmhz4rPeVKYvppfGYKSNGdyZkA01046pLWyRKKI3ax8fbJoK5QbxblURkwK/MWY18Tg==",
|
||||
"cpu": [
|
||||
"ia32"
|
||||
],
|
||||
|
|
@ -242,9 +246,9 @@
|
|||
}
|
||||
},
|
||||
"node_modules/@esbuild/linux-loong64": {
|
||||
"version": "0.19.11",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.19.11.tgz",
|
||||
"integrity": "sha512-ppZSSLVpPrwHccvC6nQVZaSHlFsvCQyjnvirnVjbKSHuE5N24Yl8F3UwYUUR1UEPaFObGD2tSvVKbvR+uT1Nrg==",
|
||||
"version": "0.21.5",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.21.5.tgz",
|
||||
"integrity": "sha512-uHf1BmMG8qEvzdrzAqg2SIG/02+4/DHB6a9Kbya0XDvwDEKCoC8ZRWI5JJvNdUjtciBGFQ5PuBlpEOXQj+JQSg==",
|
||||
"cpu": [
|
||||
"loong64"
|
||||
],
|
||||
|
|
@ -258,9 +262,9 @@
|
|||
}
|
||||
},
|
||||
"node_modules/@esbuild/linux-mips64el": {
|
||||
"version": "0.19.11",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.19.11.tgz",
|
||||
"integrity": "sha512-B5x9j0OgjG+v1dF2DkH34lr+7Gmv0kzX6/V0afF41FkPMMqaQ77pH7CrhWeR22aEeHKaeZVtZ6yFwlxOKPVFyg==",
|
||||
"version": "0.21.5",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.21.5.tgz",
|
||||
"integrity": "sha512-IajOmO+KJK23bj52dFSNCMsz1QP1DqM6cwLUv3W1QwyxkyIWecfafnI555fvSGqEKwjMXVLokcV5ygHW5b3Jbg==",
|
||||
"cpu": [
|
||||
"mips64el"
|
||||
],
|
||||
|
|
@ -274,9 +278,9 @@
|
|||
}
|
||||
},
|
||||
"node_modules/@esbuild/linux-ppc64": {
|
||||
"version": "0.19.11",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.19.11.tgz",
|
||||
"integrity": "sha512-MHrZYLeCG8vXblMetWyttkdVRjQlQUb/oMgBNurVEnhj4YWOr4G5lmBfZjHYQHHN0g6yDmCAQRR8MUHldvvRDA==",
|
||||
"version": "0.21.5",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.21.5.tgz",
|
||||
"integrity": "sha512-1hHV/Z4OEfMwpLO8rp7CvlhBDnjsC3CttJXIhBi+5Aj5r+MBvy4egg7wCbe//hSsT+RvDAG7s81tAvpL2XAE4w==",
|
||||
"cpu": [
|
||||
"ppc64"
|
||||
],
|
||||
|
|
@ -290,9 +294,9 @@
|
|||
}
|
||||
},
|
||||
"node_modules/@esbuild/linux-riscv64": {
|
||||
"version": "0.19.11",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.19.11.tgz",
|
||||
"integrity": "sha512-f3DY++t94uVg141dozDu4CCUkYW+09rWtaWfnb3bqe4w5NqmZd6nPVBm+qbz7WaHZCoqXqHz5p6CM6qv3qnSSQ==",
|
||||
"version": "0.21.5",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.21.5.tgz",
|
||||
"integrity": "sha512-2HdXDMd9GMgTGrPWnJzP2ALSokE/0O5HhTUvWIbD3YdjME8JwvSCnNGBnTThKGEB91OZhzrJ4qIIxk/SBmyDDA==",
|
||||
"cpu": [
|
||||
"riscv64"
|
||||
],
|
||||
|
|
@ -306,9 +310,9 @@
|
|||
}
|
||||
},
|
||||
"node_modules/@esbuild/linux-s390x": {
|
||||
"version": "0.19.11",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.19.11.tgz",
|
||||
"integrity": "sha512-A5xdUoyWJHMMlcSMcPGVLzYzpcY8QP1RtYzX5/bS4dvjBGVxdhuiYyFwp7z74ocV7WDc0n1harxmpq2ePOjI0Q==",
|
||||
"version": "0.21.5",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.21.5.tgz",
|
||||
"integrity": "sha512-zus5sxzqBJD3eXxwvjN1yQkRepANgxE9lgOW2qLnmr8ikMTphkjgXu1HR01K4FJg8h1kEEDAqDcZQtbrRnB41A==",
|
||||
"cpu": [
|
||||
"s390x"
|
||||
],
|
||||
|
|
@ -322,9 +326,9 @@
|
|||
}
|
||||
},
|
||||
"node_modules/@esbuild/linux-x64": {
|
||||
"version": "0.19.11",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.19.11.tgz",
|
||||
"integrity": "sha512-grbyMlVCvJSfxFQUndw5mCtWs5LO1gUlwP4CDi4iJBbVpZcqLVT29FxgGuBJGSzyOxotFG4LoO5X+M1350zmPA==",
|
||||
"version": "0.21.5",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.21.5.tgz",
|
||||
"integrity": "sha512-1rYdTpyv03iycF1+BhzrzQJCdOuAOtaqHTWJZCWvijKD2N5Xu0TtVC8/+1faWqcP9iBCWOmjmhoH94dH82BxPQ==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
|
|
@ -338,9 +342,9 @@
|
|||
}
|
||||
},
|
||||
"node_modules/@esbuild/netbsd-x64": {
|
||||
"version": "0.19.11",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.19.11.tgz",
|
||||
"integrity": "sha512-13jvrQZJc3P230OhU8xgwUnDeuC/9egsjTkXN49b3GcS5BKvJqZn86aGM8W9pd14Kd+u7HuFBMVtrNGhh6fHEQ==",
|
||||
"version": "0.21.5",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.21.5.tgz",
|
||||
"integrity": "sha512-Woi2MXzXjMULccIwMnLciyZH4nCIMpWQAs049KEeMvOcNADVxo0UBIQPfSmxB3CWKedngg7sWZdLvLczpe0tLg==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
|
|
@ -354,9 +358,9 @@
|
|||
}
|
||||
},
|
||||
"node_modules/@esbuild/openbsd-x64": {
|
||||
"version": "0.19.11",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.19.11.tgz",
|
||||
"integrity": "sha512-ysyOGZuTp6SNKPE11INDUeFVVQFrhcNDVUgSQVDzqsqX38DjhPEPATpid04LCoUr2WXhQTEZ8ct/EgJCUDpyNw==",
|
||||
"version": "0.21.5",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.21.5.tgz",
|
||||
"integrity": "sha512-HLNNw99xsvx12lFBUwoT8EVCsSvRNDVxNpjZ7bPn947b8gJPzeHWyNVhFsaerc0n3TsbOINvRP2byTZ5LKezow==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
|
|
@ -370,9 +374,9 @@
|
|||
}
|
||||
},
|
||||
"node_modules/@esbuild/sunos-x64": {
|
||||
"version": "0.19.11",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.19.11.tgz",
|
||||
"integrity": "sha512-Hf+Sad9nVwvtxy4DXCZQqLpgmRTQqyFyhT3bZ4F2XlJCjxGmRFF0Shwn9rzhOYRB61w9VMXUkxlBy56dk9JJiQ==",
|
||||
"version": "0.21.5",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.21.5.tgz",
|
||||
"integrity": "sha512-6+gjmFpfy0BHU5Tpptkuh8+uw3mnrvgs+dSPQXQOv3ekbordwnzTVEb4qnIvQcYXq6gzkyTnoZ9dZG+D4garKg==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
|
|
@ -386,9 +390,9 @@
|
|||
}
|
||||
},
|
||||
"node_modules/@esbuild/win32-arm64": {
|
||||
"version": "0.19.11",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.19.11.tgz",
|
||||
"integrity": "sha512-0P58Sbi0LctOMOQbpEOvOL44Ne0sqbS0XWHMvvrg6NE5jQ1xguCSSw9jQeUk2lfrXYsKDdOe6K+oZiwKPilYPQ==",
|
||||
"version": "0.21.5",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.21.5.tgz",
|
||||
"integrity": "sha512-Z0gOTd75VvXqyq7nsl93zwahcTROgqvuAcYDUr+vOv8uHhNSKROyU961kgtCD1e95IqPKSQKH7tBTslnS3tA8A==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
|
|
@ -402,9 +406,9 @@
|
|||
}
|
||||
},
|
||||
"node_modules/@esbuild/win32-ia32": {
|
||||
"version": "0.19.11",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.19.11.tgz",
|
||||
"integrity": "sha512-6YOrWS+sDJDmshdBIQU+Uoyh7pQKrdykdefC1avn76ss5c+RN6gut3LZA4E2cH5xUEp5/cA0+YxRaVtRAb0xBg==",
|
||||
"version": "0.21.5",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.21.5.tgz",
|
||||
"integrity": "sha512-SWXFF1CL2RVNMaVs+BBClwtfZSvDgtL//G/smwAc5oVK/UPu2Gu9tIaRgFmYFFKrmg3SyAjSrElf0TiJ1v8fYA==",
|
||||
"cpu": [
|
||||
"ia32"
|
||||
],
|
||||
|
|
@ -418,9 +422,9 @@
|
|||
}
|
||||
},
|
||||
"node_modules/@esbuild/win32-x64": {
|
||||
"version": "0.19.11",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.19.11.tgz",
|
||||
"integrity": "sha512-vfkhltrjCAb603XaFhqhAF4LGDi2M4OrCRrFusyQ+iTLQ/o60QQXxc9cZC/FFpihBI9N1Grn6SMKVJ4KP7Fuiw==",
|
||||
"version": "0.21.5",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.21.5.tgz",
|
||||
"integrity": "sha512-tQd/1efJuzPC6rCFwEvLtci/xNFcTZknmXs98FYDfGE4wP9ClFV98nyKrzJKVPMhdDnjzLhdUyMX4PsQAPjwIw==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
|
|
@ -471,9 +475,9 @@
|
|||
}
|
||||
},
|
||||
"node_modules/@rollup/rollup-android-arm-eabi": {
|
||||
"version": "4.9.4",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.9.4.tgz",
|
||||
"integrity": "sha512-ub/SN3yWqIv5CWiAZPHVS1DloyZsJbtXmX4HxUTIpS0BHm9pW5iYBo2mIZi+hE3AeiTzHz33blwSnhdUo+9NpA==",
|
||||
"version": "4.24.0",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.24.0.tgz",
|
||||
"integrity": "sha512-Q6HJd7Y6xdB48x8ZNVDOqsbh2uByBhgK8PiQgPhwkIw/HC/YX5Ghq2mQY5sRMZWHb3VsFkWooUVOZHKr7DmDIA==",
|
||||
"cpu": [
|
||||
"arm"
|
||||
],
|
||||
|
|
@ -484,9 +488,9 @@
|
|||
]
|
||||
},
|
||||
"node_modules/@rollup/rollup-android-arm64": {
|
||||
"version": "4.9.4",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.9.4.tgz",
|
||||
"integrity": "sha512-ehcBrOR5XTl0W0t2WxfTyHCR/3Cq2jfb+I4W+Ch8Y9b5G+vbAecVv0Fx/J1QKktOrgUYsIKxWAKgIpvw56IFNA==",
|
||||
"version": "4.24.0",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.24.0.tgz",
|
||||
"integrity": "sha512-ijLnS1qFId8xhKjT81uBHuuJp2lU4x2yxa4ctFPtG+MqEE6+C5f/+X/bStmxapgmwLwiL3ih122xv8kVARNAZA==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
|
|
@ -497,9 +501,9 @@
|
|||
]
|
||||
},
|
||||
"node_modules/@rollup/rollup-darwin-arm64": {
|
||||
"version": "4.9.4",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.9.4.tgz",
|
||||
"integrity": "sha512-1fzh1lWExwSTWy8vJPnNbNM02WZDS8AW3McEOb7wW+nPChLKf3WG2aG7fhaUmfX5FKw9zhsF5+MBwArGyNM7NA==",
|
||||
"version": "4.24.0",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.24.0.tgz",
|
||||
"integrity": "sha512-bIv+X9xeSs1XCk6DVvkO+S/z8/2AMt/2lMqdQbMrmVpgFvXlmde9mLcbQpztXm1tajC3raFDqegsH18HQPMYtA==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
|
|
@ -510,9 +514,9 @@
|
|||
]
|
||||
},
|
||||
"node_modules/@rollup/rollup-darwin-x64": {
|
||||
"version": "4.9.4",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.9.4.tgz",
|
||||
"integrity": "sha512-Gc6cukkF38RcYQ6uPdiXi70JB0f29CwcQ7+r4QpfNpQFVHXRd0DfWFidoGxjSx1DwOETM97JPz1RXL5ISSB0pA==",
|
||||
"version": "4.24.0",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.24.0.tgz",
|
||||
"integrity": "sha512-X6/nOwoFN7RT2svEQWUsW/5C/fYMBe4fnLK9DQk4SX4mgVBiTA9h64kjUYPvGQ0F/9xwJ5U5UfTbl6BEjaQdBQ==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
|
|
@ -523,9 +527,22 @@
|
|||
]
|
||||
},
|
||||
"node_modules/@rollup/rollup-linux-arm-gnueabihf": {
|
||||
"version": "4.9.4",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.9.4.tgz",
|
||||
"integrity": "sha512-g21RTeFzoTl8GxosHbnQZ0/JkuFIB13C3T7Y0HtKzOXmoHhewLbVTFBQZu+z5m9STH6FZ7L/oPgU4Nm5ErN2fw==",
|
||||
"version": "4.24.0",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.24.0.tgz",
|
||||
"integrity": "sha512-0KXvIJQMOImLCVCz9uvvdPgfyWo93aHHp8ui3FrtOP57svqrF/roSSR5pjqL2hcMp0ljeGlU4q9o/rQaAQ3AYA==",
|
||||
"cpu": [
|
||||
"arm"
|
||||
],
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
]
|
||||
},
|
||||
"node_modules/@rollup/rollup-linux-arm-musleabihf": {
|
||||
"version": "4.24.0",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.24.0.tgz",
|
||||
"integrity": "sha512-it2BW6kKFVh8xk/BnHfakEeoLPv8STIISekpoF+nBgWM4d55CZKc7T4Dx1pEbTnYm/xEKMgy1MNtYuoA8RFIWw==",
|
||||
"cpu": [
|
||||
"arm"
|
||||
],
|
||||
|
|
@ -536,9 +553,9 @@
|
|||
]
|
||||
},
|
||||
"node_modules/@rollup/rollup-linux-arm64-gnu": {
|
||||
"version": "4.9.4",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.9.4.tgz",
|
||||
"integrity": "sha512-TVYVWD/SYwWzGGnbfTkrNpdE4HON46orgMNHCivlXmlsSGQOx/OHHYiQcMIOx38/GWgwr/po2LBn7wypkWw/Mg==",
|
||||
"version": "4.24.0",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.24.0.tgz",
|
||||
"integrity": "sha512-i0xTLXjqap2eRfulFVlSnM5dEbTVque/3Pi4g2y7cxrs7+a9De42z4XxKLYJ7+OhE3IgxvfQM7vQc43bwTgPwA==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
|
|
@ -549,9 +566,9 @@
|
|||
]
|
||||
},
|
||||
"node_modules/@rollup/rollup-linux-arm64-musl": {
|
||||
"version": "4.9.4",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.9.4.tgz",
|
||||
"integrity": "sha512-XcKvuendwizYYhFxpvQ3xVpzje2HHImzg33wL9zvxtj77HvPStbSGI9czrdbfrf8DGMcNNReH9pVZv8qejAQ5A==",
|
||||
"version": "4.24.0",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.24.0.tgz",
|
||||
"integrity": "sha512-9E6MKUJhDuDh604Qco5yP/3qn3y7SLXYuiC0Rpr89aMScS2UAmK1wHP2b7KAa1nSjWJc/f/Lc0Wl1L47qjiyQw==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
|
|
@ -561,10 +578,23 @@
|
|||
"linux"
|
||||
]
|
||||
},
|
||||
"node_modules/@rollup/rollup-linux-powerpc64le-gnu": {
|
||||
"version": "4.24.0",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.24.0.tgz",
|
||||
"integrity": "sha512-2XFFPJ2XMEiF5Zi2EBf4h73oR1V/lycirxZxHZNc93SqDN/IWhYYSYj8I9381ikUFXZrz2v7r2tOVk2NBwxrWw==",
|
||||
"cpu": [
|
||||
"ppc64"
|
||||
],
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
]
|
||||
},
|
||||
"node_modules/@rollup/rollup-linux-riscv64-gnu": {
|
||||
"version": "4.9.4",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.9.4.tgz",
|
||||
"integrity": "sha512-LFHS/8Q+I9YA0yVETyjonMJ3UA+DczeBd/MqNEzsGSTdNvSJa1OJZcSH8GiXLvcizgp9AlHs2walqRcqzjOi3A==",
|
||||
"version": "4.24.0",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.24.0.tgz",
|
||||
"integrity": "sha512-M3Dg4hlwuntUCdzU7KjYqbbd+BLq3JMAOhCKdBE3TcMGMZbKkDdJ5ivNdehOssMCIokNHFOsv7DO4rlEOfyKpg==",
|
||||
"cpu": [
|
||||
"riscv64"
|
||||
],
|
||||
|
|
@ -574,10 +604,23 @@
|
|||
"linux"
|
||||
]
|
||||
},
|
||||
"node_modules/@rollup/rollup-linux-s390x-gnu": {
|
||||
"version": "4.24.0",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.24.0.tgz",
|
||||
"integrity": "sha512-mjBaoo4ocxJppTorZVKWFpy1bfFj9FeCMJqzlMQGjpNPY9JwQi7OuS1axzNIk0nMX6jSgy6ZURDZ2w0QW6D56g==",
|
||||
"cpu": [
|
||||
"s390x"
|
||||
],
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
]
|
||||
},
|
||||
"node_modules/@rollup/rollup-linux-x64-gnu": {
|
||||
"version": "4.9.4",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.9.4.tgz",
|
||||
"integrity": "sha512-dIYgo+j1+yfy81i0YVU5KnQrIJZE8ERomx17ReU4GREjGtDW4X+nvkBak2xAUpyqLs4eleDSj3RrV72fQos7zw==",
|
||||
"version": "4.24.0",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.24.0.tgz",
|
||||
"integrity": "sha512-ZXFk7M72R0YYFN5q13niV0B7G8/5dcQ9JDp8keJSfr3GoZeXEoMHP/HlvqROA3OMbMdfr19IjCeNAnPUG93b6A==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
|
|
@ -588,9 +631,9 @@
|
|||
]
|
||||
},
|
||||
"node_modules/@rollup/rollup-linux-x64-musl": {
|
||||
"version": "4.9.4",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.9.4.tgz",
|
||||
"integrity": "sha512-RoaYxjdHQ5TPjaPrLsfKqR3pakMr3JGqZ+jZM0zP2IkDtsGa4CqYaWSfQmZVgFUCgLrTnzX+cnHS3nfl+kB6ZQ==",
|
||||
"version": "4.24.0",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.24.0.tgz",
|
||||
"integrity": "sha512-w1i+L7kAXZNdYl+vFvzSZy8Y1arS7vMgIy8wusXJzRrPyof5LAb02KGr1PD2EkRcl73kHulIID0M501lN+vobQ==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
|
|
@ -601,9 +644,9 @@
|
|||
]
|
||||
},
|
||||
"node_modules/@rollup/rollup-win32-arm64-msvc": {
|
||||
"version": "4.9.4",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.9.4.tgz",
|
||||
"integrity": "sha512-T8Q3XHV+Jjf5e49B4EAaLKV74BbX7/qYBRQ8Wop/+TyyU0k+vSjiLVSHNWdVd1goMjZcbhDmYZUYW5RFqkBNHQ==",
|
||||
"version": "4.24.0",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.24.0.tgz",
|
||||
"integrity": "sha512-VXBrnPWgBpVDCVY6XF3LEW0pOU51KbaHhccHw6AS6vBWIC60eqsH19DAeeObl+g8nKAz04QFdl/Cefta0xQtUQ==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
|
|
@ -614,9 +657,9 @@
|
|||
]
|
||||
},
|
||||
"node_modules/@rollup/rollup-win32-ia32-msvc": {
|
||||
"version": "4.9.4",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.9.4.tgz",
|
||||
"integrity": "sha512-z+JQ7JirDUHAsMecVydnBPWLwJjbppU+7LZjffGf+Jvrxq+dVjIE7By163Sc9DKc3ADSU50qPVw0KonBS+a+HQ==",
|
||||
"version": "4.24.0",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.24.0.tgz",
|
||||
"integrity": "sha512-xrNcGDU0OxVcPTH/8n/ShH4UevZxKIO6HJFK0e15XItZP2UcaiLFd5kiX7hJnqCbSztUF8Qot+JWBC/QXRPYWQ==",
|
||||
"cpu": [
|
||||
"ia32"
|
||||
],
|
||||
|
|
@ -627,9 +670,9 @@
|
|||
]
|
||||
},
|
||||
"node_modules/@rollup/rollup-win32-x64-msvc": {
|
||||
"version": "4.9.4",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.9.4.tgz",
|
||||
"integrity": "sha512-LfdGXCV9rdEify1oxlN9eamvDSjv9md9ZVMAbNHA87xqIfFCxImxan9qZ8+Un54iK2nnqPlbnSi4R54ONtbWBw==",
|
||||
"version": "4.24.0",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.24.0.tgz",
|
||||
"integrity": "sha512-fbMkAF7fufku0N2dE5TBXcNlg0pt0cJue4xBRE2Qc5Vqikxr4VCgKj/ht6SMdFcOacVA9rqF70APJ8RN/4vMJw==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
|
|
@ -640,9 +683,9 @@
|
|||
]
|
||||
},
|
||||
"node_modules/@types/estree": {
|
||||
"version": "1.0.5",
|
||||
"resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.5.tgz",
|
||||
"integrity": "sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==",
|
||||
"version": "1.0.6",
|
||||
"resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.6.tgz",
|
||||
"integrity": "sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/@types/lodash": {
|
||||
|
|
@ -968,6 +1011,11 @@
|
|||
"node": ">= 8"
|
||||
}
|
||||
},
|
||||
"node_modules/argparse": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz",
|
||||
"integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q=="
|
||||
},
|
||||
"node_modules/async-validator": {
|
||||
"version": "4.2.5",
|
||||
"resolved": "https://registry.npmjs.org/async-validator/-/async-validator-4.2.5.tgz",
|
||||
|
|
@ -979,11 +1027,11 @@
|
|||
"integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q=="
|
||||
},
|
||||
"node_modules/axios": {
|
||||
"version": "1.6.5",
|
||||
"resolved": "https://registry.npmjs.org/axios/-/axios-1.6.5.tgz",
|
||||
"integrity": "sha512-Ii012v05KEVuUoFWmMW/UQv9aRIc3ZwkWDcM+h5Il8izZCtRVpDUfwpoFf7eOtajT3QiGR4yDUx7lPqHJULgbg==",
|
||||
"version": "1.7.7",
|
||||
"resolved": "https://registry.npmjs.org/axios/-/axios-1.7.7.tgz",
|
||||
"integrity": "sha512-S4kL7XrjgBmvdGut0sN3yJxqYzrDOnivkBiN0OFs6hLiUam3UPvswUo0kqGyhqUZGEOytHyumEdXsAkgCOUf3Q==",
|
||||
"dependencies": {
|
||||
"follow-redirects": "^1.15.4",
|
||||
"follow-redirects": "^1.15.6",
|
||||
"form-data": "^4.0.0",
|
||||
"proxy-from-env": "^1.1.0"
|
||||
}
|
||||
|
|
@ -1011,12 +1059,12 @@
|
|||
}
|
||||
},
|
||||
"node_modules/braces": {
|
||||
"version": "3.0.2",
|
||||
"resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz",
|
||||
"integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==",
|
||||
"version": "3.0.3",
|
||||
"resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz",
|
||||
"integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"fill-range": "^7.0.1"
|
||||
"fill-range": "^7.1.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
|
|
@ -1208,9 +1256,9 @@
|
|||
}
|
||||
},
|
||||
"node_modules/esbuild": {
|
||||
"version": "0.19.11",
|
||||
"resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.19.11.tgz",
|
||||
"integrity": "sha512-HJ96Hev2hX/6i5cDVwcqiJBBtuo9+FeIJOtZ9W1kA5M6AMJRHUZlpYZ1/SbEwtO0ioNAW8rUooVpC/WehY2SfA==",
|
||||
"version": "0.21.5",
|
||||
"resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.21.5.tgz",
|
||||
"integrity": "sha512-mg3OPMV4hXywwpoDxu3Qda5xCKQi+vCTZq8S9J/EpkhB2HzKXq4SNFZE3+NK93JYxc8VMSep+lOUSC/RVKaBqw==",
|
||||
"dev": true,
|
||||
"hasInstallScript": true,
|
||||
"bin": {
|
||||
|
|
@ -1220,29 +1268,29 @@
|
|||
"node": ">=12"
|
||||
},
|
||||
"optionalDependencies": {
|
||||
"@esbuild/aix-ppc64": "0.19.11",
|
||||
"@esbuild/android-arm": "0.19.11",
|
||||
"@esbuild/android-arm64": "0.19.11",
|
||||
"@esbuild/android-x64": "0.19.11",
|
||||
"@esbuild/darwin-arm64": "0.19.11",
|
||||
"@esbuild/darwin-x64": "0.19.11",
|
||||
"@esbuild/freebsd-arm64": "0.19.11",
|
||||
"@esbuild/freebsd-x64": "0.19.11",
|
||||
"@esbuild/linux-arm": "0.19.11",
|
||||
"@esbuild/linux-arm64": "0.19.11",
|
||||
"@esbuild/linux-ia32": "0.19.11",
|
||||
"@esbuild/linux-loong64": "0.19.11",
|
||||
"@esbuild/linux-mips64el": "0.19.11",
|
||||
"@esbuild/linux-ppc64": "0.19.11",
|
||||
"@esbuild/linux-riscv64": "0.19.11",
|
||||
"@esbuild/linux-s390x": "0.19.11",
|
||||
"@esbuild/linux-x64": "0.19.11",
|
||||
"@esbuild/netbsd-x64": "0.19.11",
|
||||
"@esbuild/openbsd-x64": "0.19.11",
|
||||
"@esbuild/sunos-x64": "0.19.11",
|
||||
"@esbuild/win32-arm64": "0.19.11",
|
||||
"@esbuild/win32-ia32": "0.19.11",
|
||||
"@esbuild/win32-x64": "0.19.11"
|
||||
"@esbuild/aix-ppc64": "0.21.5",
|
||||
"@esbuild/android-arm": "0.21.5",
|
||||
"@esbuild/android-arm64": "0.21.5",
|
||||
"@esbuild/android-x64": "0.21.5",
|
||||
"@esbuild/darwin-arm64": "0.21.5",
|
||||
"@esbuild/darwin-x64": "0.21.5",
|
||||
"@esbuild/freebsd-arm64": "0.21.5",
|
||||
"@esbuild/freebsd-x64": "0.21.5",
|
||||
"@esbuild/linux-arm": "0.21.5",
|
||||
"@esbuild/linux-arm64": "0.21.5",
|
||||
"@esbuild/linux-ia32": "0.21.5",
|
||||
"@esbuild/linux-loong64": "0.21.5",
|
||||
"@esbuild/linux-mips64el": "0.21.5",
|
||||
"@esbuild/linux-ppc64": "0.21.5",
|
||||
"@esbuild/linux-riscv64": "0.21.5",
|
||||
"@esbuild/linux-s390x": "0.21.5",
|
||||
"@esbuild/linux-x64": "0.21.5",
|
||||
"@esbuild/netbsd-x64": "0.21.5",
|
||||
"@esbuild/openbsd-x64": "0.21.5",
|
||||
"@esbuild/sunos-x64": "0.21.5",
|
||||
"@esbuild/win32-arm64": "0.21.5",
|
||||
"@esbuild/win32-ia32": "0.21.5",
|
||||
"@esbuild/win32-x64": "0.21.5"
|
||||
}
|
||||
},
|
||||
"node_modules/escape-html": {
|
||||
|
|
@ -1256,9 +1304,9 @@
|
|||
"integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w=="
|
||||
},
|
||||
"node_modules/fill-range": {
|
||||
"version": "7.0.1",
|
||||
"resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz",
|
||||
"integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==",
|
||||
"version": "7.1.1",
|
||||
"resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz",
|
||||
"integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"to-regex-range": "^5.0.1"
|
||||
|
|
@ -1280,9 +1328,9 @@
|
|||
}
|
||||
},
|
||||
"node_modules/follow-redirects": {
|
||||
"version": "1.15.4",
|
||||
"resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.4.tgz",
|
||||
"integrity": "sha512-Cr4D/5wlrb0z9dgERpUL3LrmPKVDsETIJhaCMeDfuFYcqa5bldGV6wBsAN6X/vxlXQtFBMrXdXxdL8CbDTGniw==",
|
||||
"version": "1.15.9",
|
||||
"resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.9.tgz",
|
||||
"integrity": "sha512-gew4GsXizNgdoRyqmyfMHyAmXsZDk6mHkSxZFCzW9gwlbtOW44CDtYavM+y+72qD/Vq2l550kMF52DT8fOLJqQ==",
|
||||
"funding": [
|
||||
{
|
||||
"type": "individual",
|
||||
|
|
@ -1378,6 +1426,14 @@
|
|||
"process": "^0.11.10"
|
||||
}
|
||||
},
|
||||
"node_modules/highlight.js": {
|
||||
"version": "11.11.1",
|
||||
"resolved": "https://registry.npmjs.org/highlight.js/-/highlight.js-11.11.1.tgz",
|
||||
"integrity": "sha512-Xwwo44whKBVCYoliBQwaPvtd/2tYFkRQtXDWj1nackaV2JPXx3L0+Jvd8/qCJ2p+ML0/XVkJ2q+Mr+UVdpJK5w==",
|
||||
"engines": {
|
||||
"node": ">=12.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/immutable": {
|
||||
"version": "4.3.4",
|
||||
"resolved": "https://registry.npmjs.org/immutable/-/immutable-4.3.4.tgz",
|
||||
|
|
@ -1482,6 +1538,14 @@
|
|||
"resolved": "https://registry.npmjs.org/keycode/-/keycode-2.2.0.tgz",
|
||||
"integrity": "sha512-ps3I9jAdNtRpJrbBvQjpzyFbss/skHqzS+eu4RxKLaEAtFqkjZaB6TZMSivPbLxf4K7VI4SjR0P5mRCX5+Q25A=="
|
||||
},
|
||||
"node_modules/linkify-it": {
|
||||
"version": "5.0.0",
|
||||
"resolved": "https://registry.npmjs.org/linkify-it/-/linkify-it-5.0.0.tgz",
|
||||
"integrity": "sha512-5aHCbzQRADcdP+ATqnDuhhJ/MRIqDkZX5pyjFHRRysS8vZ5AbqGEoFIb6pYHPZ+L/OC2Lc+xT8uHVVR5CAK/wQ==",
|
||||
"dependencies": {
|
||||
"uc.micro": "^2.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/locate-path": {
|
||||
"version": "5.0.0",
|
||||
"resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz",
|
||||
|
|
@ -1548,6 +1612,27 @@
|
|||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/markdown-it": {
|
||||
"version": "14.1.0",
|
||||
"resolved": "https://registry.npmmirror.com/markdown-it/-/markdown-it-14.1.0.tgz",
|
||||
"integrity": "sha512-a54IwgWPaeBCAAsv13YgmALOF1elABB08FxO9i+r4VFk5Vl4pKokRPeX8u5TCgSsPi6ec1otfLjdOpVcgbpshg==",
|
||||
"dependencies": {
|
||||
"argparse": "^2.0.1",
|
||||
"entities": "^4.4.0",
|
||||
"linkify-it": "^5.0.0",
|
||||
"mdurl": "^2.0.0",
|
||||
"punycode.js": "^2.3.1",
|
||||
"uc.micro": "^2.1.0"
|
||||
},
|
||||
"bin": {
|
||||
"markdown-it": "bin/markdown-it.mjs"
|
||||
}
|
||||
},
|
||||
"node_modules/mdurl": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/mdurl/-/mdurl-2.0.0.tgz",
|
||||
"integrity": "sha512-Lf+9+2r+Tdp5wXDXC4PcIBjTDtq4UKjCPMQhKIuzpJNW0b96kVqSwW0bT7FhRSfmAiFYgP+SCRvdrDozfh0U5w=="
|
||||
},
|
||||
"node_modules/memoize-one": {
|
||||
"version": "6.0.0",
|
||||
"resolved": "https://registry.npmjs.org/memoize-one/-/memoize-one-6.0.0.tgz",
|
||||
|
|
@ -1726,9 +1811,9 @@
|
|||
}
|
||||
},
|
||||
"node_modules/picocolors": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz",
|
||||
"integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ=="
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.0.tgz",
|
||||
"integrity": "sha512-TQ92mBOW0l3LeMeyLV6mzy/kWr8lkd/hp3mTg7wYK7zJhuBStmGMBG0BdeDZS/dZx1IukaX6Bk11zcln25o1Aw=="
|
||||
},
|
||||
"node_modules/picomatch": {
|
||||
"version": "2.3.1",
|
||||
|
|
@ -1762,9 +1847,9 @@
|
|||
}
|
||||
},
|
||||
"node_modules/postcss": {
|
||||
"version": "8.4.33",
|
||||
"resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.33.tgz",
|
||||
"integrity": "sha512-Kkpbhhdjw2qQs2O2DGX+8m5OVqEcbB9HRBvuYM9pgrjEFUg30A9LmXNlTAUj4S9kgtGyrMbTzVjH7E+s5Re2yg==",
|
||||
"version": "8.4.47",
|
||||
"resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.47.tgz",
|
||||
"integrity": "sha512-56rxCq7G/XfB4EkXq9Egn5GCqugWvDFjafDOThIdMBsI15iqPqR5r15TfSr1YPYeEI19YeaXMCbY6u88Y76GLQ==",
|
||||
"funding": [
|
||||
{
|
||||
"type": "opencollective",
|
||||
|
|
@ -1781,8 +1866,8 @@
|
|||
],
|
||||
"dependencies": {
|
||||
"nanoid": "^3.3.7",
|
||||
"picocolors": "^1.0.0",
|
||||
"source-map-js": "^1.0.2"
|
||||
"picocolors": "^1.1.0",
|
||||
"source-map-js": "^1.2.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": "^10 || ^12 || >=14"
|
||||
|
|
@ -1801,6 +1886,14 @@
|
|||
"resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz",
|
||||
"integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg=="
|
||||
},
|
||||
"node_modules/punycode.js": {
|
||||
"version": "2.3.1",
|
||||
"resolved": "https://registry.npmjs.org/punycode.js/-/punycode.js-2.3.1.tgz",
|
||||
"integrity": "sha512-uxFIHU0YlHYhDQtV4R9J6a52SLx28BCjT+4ieh7IGbgwVJWO+km431c4yRlREUAsAmt/uMjQUyQHNEPf0M39CA==",
|
||||
"engines": {
|
||||
"node": ">=6"
|
||||
}
|
||||
},
|
||||
"node_modules/qrcode": {
|
||||
"version": "1.5.3",
|
||||
"resolved": "https://registry.npmjs.org/qrcode/-/qrcode-1.5.3.tgz",
|
||||
|
|
@ -1849,12 +1942,12 @@
|
|||
"integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg=="
|
||||
},
|
||||
"node_modules/rollup": {
|
||||
"version": "4.9.4",
|
||||
"resolved": "https://registry.npmjs.org/rollup/-/rollup-4.9.4.tgz",
|
||||
"integrity": "sha512-2ztU7pY/lrQyXSCnnoU4ICjT/tCG9cdH3/G25ERqE3Lst6vl2BCM5hL2Nw+sslAvAf+ccKsAq1SkKQALyqhR7g==",
|
||||
"version": "4.24.0",
|
||||
"resolved": "https://registry.npmjs.org/rollup/-/rollup-4.24.0.tgz",
|
||||
"integrity": "sha512-DOmrlGSXNk1DM0ljiQA+i+o0rSLhtii1je5wgk60j49d1jHT5YYttBv1iWOnYSTG+fZZESUOSNiAl89SIet+Cg==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@types/estree": "1.0.5"
|
||||
"@types/estree": "1.0.6"
|
||||
},
|
||||
"bin": {
|
||||
"rollup": "dist/bin/rollup"
|
||||
|
|
@ -1864,19 +1957,22 @@
|
|||
"npm": ">=8.0.0"
|
||||
},
|
||||
"optionalDependencies": {
|
||||
"@rollup/rollup-android-arm-eabi": "4.9.4",
|
||||
"@rollup/rollup-android-arm64": "4.9.4",
|
||||
"@rollup/rollup-darwin-arm64": "4.9.4",
|
||||
"@rollup/rollup-darwin-x64": "4.9.4",
|
||||
"@rollup/rollup-linux-arm-gnueabihf": "4.9.4",
|
||||
"@rollup/rollup-linux-arm64-gnu": "4.9.4",
|
||||
"@rollup/rollup-linux-arm64-musl": "4.9.4",
|
||||
"@rollup/rollup-linux-riscv64-gnu": "4.9.4",
|
||||
"@rollup/rollup-linux-x64-gnu": "4.9.4",
|
||||
"@rollup/rollup-linux-x64-musl": "4.9.4",
|
||||
"@rollup/rollup-win32-arm64-msvc": "4.9.4",
|
||||
"@rollup/rollup-win32-ia32-msvc": "4.9.4",
|
||||
"@rollup/rollup-win32-x64-msvc": "4.9.4",
|
||||
"@rollup/rollup-android-arm-eabi": "4.24.0",
|
||||
"@rollup/rollup-android-arm64": "4.24.0",
|
||||
"@rollup/rollup-darwin-arm64": "4.24.0",
|
||||
"@rollup/rollup-darwin-x64": "4.24.0",
|
||||
"@rollup/rollup-linux-arm-gnueabihf": "4.24.0",
|
||||
"@rollup/rollup-linux-arm-musleabihf": "4.24.0",
|
||||
"@rollup/rollup-linux-arm64-gnu": "4.24.0",
|
||||
"@rollup/rollup-linux-arm64-musl": "4.24.0",
|
||||
"@rollup/rollup-linux-powerpc64le-gnu": "4.24.0",
|
||||
"@rollup/rollup-linux-riscv64-gnu": "4.24.0",
|
||||
"@rollup/rollup-linux-s390x-gnu": "4.24.0",
|
||||
"@rollup/rollup-linux-x64-gnu": "4.24.0",
|
||||
"@rollup/rollup-linux-x64-musl": "4.24.0",
|
||||
"@rollup/rollup-win32-arm64-msvc": "4.24.0",
|
||||
"@rollup/rollup-win32-ia32-msvc": "4.24.0",
|
||||
"@rollup/rollup-win32-x64-msvc": "4.24.0",
|
||||
"fsevents": "~2.3.2"
|
||||
}
|
||||
},
|
||||
|
|
@ -1962,13 +2058,18 @@
|
|||
}
|
||||
},
|
||||
"node_modules/source-map-js": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.2.tgz",
|
||||
"integrity": "sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==",
|
||||
"version": "1.2.1",
|
||||
"resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz",
|
||||
"integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==",
|
||||
"engines": {
|
||||
"node": ">=0.10.0"
|
||||
}
|
||||
},
|
||||
"node_modules/spark-md5": {
|
||||
"version": "3.0.2",
|
||||
"resolved": "https://registry.npmjs.org/spark-md5/-/spark-md5-3.0.2.tgz",
|
||||
"integrity": "sha512-wcFzz9cDfbuqe0FZzfi2or1sgyIrsDwmPwfZC4hiNidPdPINjeUwNfv5kldczoEAcjl9Y1L3SM7Uz2PUEQzxQw=="
|
||||
},
|
||||
"node_modules/string-split-by": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/string-split-by/-/string-split-by-1.0.0.tgz",
|
||||
|
|
@ -2013,6 +2114,11 @@
|
|||
"node": ">=8.0"
|
||||
}
|
||||
},
|
||||
"node_modules/uc.micro": {
|
||||
"version": "2.1.0",
|
||||
"resolved": "https://registry.npmjs.org/uc.micro/-/uc.micro-2.1.0.tgz",
|
||||
"integrity": "sha512-ARDJmphmdvUk6Glw7y9DQ2bFkKBHwQHLi2lsaH6PPmz/Ka9sFOBsBluozhDltWmnv9u/cF6Rt87znRTPV+yp/A=="
|
||||
},
|
||||
"node_modules/url-toolkit": {
|
||||
"version": "2.2.5",
|
||||
"resolved": "https://registry.npmjs.org/url-toolkit/-/url-toolkit-2.2.5.tgz",
|
||||
|
|
@ -2026,6 +2132,10 @@
|
|||
"node": ">= 0.8"
|
||||
}
|
||||
},
|
||||
"node_modules/video_ca": {
|
||||
"resolved": "",
|
||||
"link": true
|
||||
},
|
||||
"node_modules/video.js": {
|
||||
"version": "8.9.0",
|
||||
"resolved": "https://registry.npmjs.org/video.js/-/video.js-8.9.0.tgz",
|
||||
|
|
@ -2076,14 +2186,14 @@
|
|||
}
|
||||
},
|
||||
"node_modules/vite": {
|
||||
"version": "5.0.11",
|
||||
"resolved": "https://registry.npmjs.org/vite/-/vite-5.0.11.tgz",
|
||||
"integrity": "sha512-XBMnDjZcNAw/G1gEiskiM1v6yzM4GE5aMGvhWTlHAYYhxb7S3/V1s3m2LDHa8Vh6yIWYYB0iJwsEaS523c4oYA==",
|
||||
"version": "5.4.8",
|
||||
"resolved": "https://registry.npmjs.org/vite/-/vite-5.4.8.tgz",
|
||||
"integrity": "sha512-FqrItQ4DT1NC4zCUqMB4c4AZORMKIa0m8/URVCZ77OZ/QSNeJ54bU1vrFADbDsuwfIPcgknRkmqakQcgnL4GiQ==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"esbuild": "^0.19.3",
|
||||
"postcss": "^8.4.32",
|
||||
"rollup": "^4.2.0"
|
||||
"esbuild": "^0.21.3",
|
||||
"postcss": "^8.4.43",
|
||||
"rollup": "^4.20.0"
|
||||
},
|
||||
"bin": {
|
||||
"vite": "bin/vite.js"
|
||||
|
|
@ -2102,6 +2212,7 @@
|
|||
"less": "*",
|
||||
"lightningcss": "^1.21.0",
|
||||
"sass": "*",
|
||||
"sass-embedded": "*",
|
||||
"stylus": "*",
|
||||
"sugarss": "*",
|
||||
"terser": "^5.4.0"
|
||||
|
|
@ -2119,6 +2230,9 @@
|
|||
"sass": {
|
||||
"optional": true
|
||||
},
|
||||
"sass-embedded": {
|
||||
"optional": true
|
||||
},
|
||||
"stylus": {
|
||||
"optional": true
|
||||
},
|
||||
|
|
|
|||
|
|
@ -13,9 +13,13 @@
|
|||
"cors": "^2.8.5",
|
||||
"crypto-js": "^4.2.0",
|
||||
"element-plus": "^2.4.4",
|
||||
"highlight.js": "^11.11.1",
|
||||
"js-cookie": "^3.0.5",
|
||||
"js-md5": "^0.8.3",
|
||||
"markdown-it": "^14.1.0",
|
||||
"qrcode": "^1.5.3",
|
||||
"spark-md5": "^3.0.2",
|
||||
"video_ca": "file:",
|
||||
"video.js": "^8.9.0",
|
||||
"vue": "^3.3.11",
|
||||
"vue-cookies": "^1.8.3",
|
||||
|
|
|
|||
|
|
@ -0,0 +1,103 @@
|
|||
import request from '@/utils/request.js'
|
||||
|
||||
export const getFriendListService = (data) => {
|
||||
const params = new URLSearchParams();
|
||||
for (let d in data) {
|
||||
if(d == "token") continue;
|
||||
params.append(d, data[d]);
|
||||
}
|
||||
// request.headers["Content-Type"] = "application/json";
|
||||
request.defaults.headers["token"] = data.token.value;
|
||||
return request.post('/im/get_friend_list', params, {
|
||||
headers: {
|
||||
'token': data.token, // 将 token 替换为您的令牌值
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
export const getGroupFriendListService = (data) => {
|
||||
const params = new URLSearchParams();
|
||||
for (let d in data) {
|
||||
if(d == "token") continue;
|
||||
params.append(d, data[d]);
|
||||
}
|
||||
// request.headers["Content-Type"] = "application/json";
|
||||
request.defaults.headers["token"] = data.token.value;
|
||||
return request.post('/im/get_group_req_user', params, {
|
||||
headers: {
|
||||
'token': data.token, // 将 token 替换为您的令牌值
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
export const getFriendReqService = (Data) => {
|
||||
const params = new URLSearchParams();
|
||||
for (let key in Data) {
|
||||
if(key == "token") continue;
|
||||
params.append(key, Data[key])
|
||||
}
|
||||
request.defaults.headers["token"] = Data.token.value;
|
||||
return request.post('/im/get_friend_request', params, {
|
||||
headers: {
|
||||
'token': Data.token,
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
export const getGroupUsersListService = (data) => {
|
||||
const params = new URLSearchParams();
|
||||
for (let d in data) {
|
||||
if(d == "token") continue;
|
||||
params.append(d, data[d]);
|
||||
}
|
||||
// request.headers["Content-Type"] = "application/json";
|
||||
request.defaults.headers["token"] = data.token.value;
|
||||
return request.post('/im/get_group_users_info', params, {
|
||||
headers: {
|
||||
'token': data.token, // 将 token <20><>换为您的令牌值
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
export const getMessageService = (data) => {
|
||||
const params = new URLSearchParams();
|
||||
for (let d in data) {
|
||||
if(d == "token") continue;
|
||||
params.append(d, data[d]);
|
||||
}
|
||||
// request.headers["Content-Type"] = "application/json";
|
||||
request.defaults.headers["token"] = data.token.value;
|
||||
return request.post('/im/get_message', params, {
|
||||
headers: {
|
||||
'token': data.token // 将 token 替换为您的令牌值
|
||||
}
|
||||
}
|
||||
);
|
||||
};
|
||||
|
||||
export const sendMessageService = (data) => {
|
||||
const params = new URLSearchParams();
|
||||
for (let d in data) {
|
||||
if(d == "token") continue;
|
||||
params.append(d, data[d]);
|
||||
}
|
||||
// request.headers["Content-Type"] = "application/json";
|
||||
request.defaults.headers["token"] = data.token.value;
|
||||
return request.post('/im/send_message', params, {
|
||||
headers: {
|
||||
'token': data.token, // 将 token 替换为您的令牌值
|
||||
}
|
||||
}
|
||||
);
|
||||
};
|
||||
|
||||
export const addGroupService = (data) => {
|
||||
const params = new URLSearchParams();
|
||||
for (let key in data) {
|
||||
if(key == "token") continue;
|
||||
params.append(key, data[key])
|
||||
}
|
||||
return request.post('/im/create_group', params, { "headers": { 'token': data.token },'Content-Type': 'application/json' });
|
||||
}
|
||||
108
src/api/cid.js
108
src/api/cid.js
|
|
@ -1,65 +1,95 @@
|
|||
import request from '@/utils/request.js'
|
||||
import request from '@/utils/request.js';
|
||||
import request_aliyun from '@/utils/aliyun_erver.js';
|
||||
import { createRequestInstance } from '@/utils/req_base.js';
|
||||
|
||||
export const runCIDService = (data) => {
|
||||
const params = new URLSearchParams();
|
||||
for (let key in data) {
|
||||
if(key == 'token') continue;
|
||||
params.append(key, data[key])
|
||||
}
|
||||
return request.post('/cid/run', params, { "headers": { 'token': data.token } });
|
||||
let request1 = getRequest();
|
||||
let token = data.token;
|
||||
const { token: _, ...requestData } = data;
|
||||
return request1.post('/cid/run', requestData, { "headers": { 'token': token } });
|
||||
}
|
||||
|
||||
export const updateCIDService = (data) => {
|
||||
const params = new URLSearchParams();
|
||||
for (let key in data) {
|
||||
if (key == 'token') continue;
|
||||
params.append(key, data[key])
|
||||
}
|
||||
return request.post('/cid/update', params, { "headers": { 'token': data.token } });
|
||||
// const params = new URLSearchParams();
|
||||
// for (let key in data) {
|
||||
// if (key == 'token') continue;
|
||||
// params.append(key, data[key])
|
||||
// }
|
||||
let request1 = getRequest();
|
||||
let token = data.token;
|
||||
const { token: _, ...requestData } = data;
|
||||
return request1.post('/cid/update', requestData, { "headers": { 'token': token } });
|
||||
}
|
||||
|
||||
export const deleteCIDService = (data) => {
|
||||
const params = new URLSearchParams();
|
||||
for (let key in data) {
|
||||
params.append(key, data[key])
|
||||
}
|
||||
return request.post('/cid/delete', params, { "headers": { 'token': data.token } });
|
||||
// const params = new URLSearchParams();
|
||||
// for (let key in data) {
|
||||
// params.append(key, data[key])
|
||||
// }
|
||||
let request1 =getRequest();
|
||||
let token = data.token;
|
||||
const { token: _, ...requestData } = data;
|
||||
return request1.post('/cid/delete', requestData, { "headers": { 'token': token } });
|
||||
}
|
||||
|
||||
export const addCIDService = (data) => {
|
||||
const params = new URLSearchParams();
|
||||
for (let key in data) {
|
||||
params.append(key, data[key])
|
||||
}
|
||||
return request.post('/cid/create', params, { "headers": { 'token': data.token },'Content-Type': 'application/json' });
|
||||
// const params = new URLSearchParams();
|
||||
// for (let key in data) {
|
||||
// params.append(key, data[key])
|
||||
// }
|
||||
let request1 = getRequest();
|
||||
let token = data.token;
|
||||
delete data.token;
|
||||
return request1.post('/cid/create', data, { "headers": { 'token': token }, 'Content-Type': 'application/json' });
|
||||
|
||||
}
|
||||
|
||||
export const getCIDListService = (data) => {
|
||||
const params = new URLSearchParams();
|
||||
for (let d in data) {
|
||||
params.append(d, data[d]);
|
||||
}
|
||||
// request.headers["Content-Type"] = "application/json";
|
||||
request.defaults.headers["token"] = data.token.value;
|
||||
return request.post('/cid/list', params, {
|
||||
let request1 = getRequest();
|
||||
let token = data.token;
|
||||
const { token: _, ...requestData } = data;
|
||||
return request1.post('/cid/list', requestData, {
|
||||
headers: {
|
||||
'token': data.token, // 将 token 替换为您的令牌值
|
||||
'token': token, // 将 token 替换为您的令牌值
|
||||
}
|
||||
}
|
||||
);
|
||||
// request.headers["Content-Type"] = "application/json";
|
||||
|
||||
}
|
||||
|
||||
export const getCIDLogListService = (data) => {
|
||||
const params = new URLSearchParams();
|
||||
for (let d in data) {
|
||||
params.append(d, data[d]);
|
||||
}
|
||||
// request.headers["Content-Type"] = "application/json";
|
||||
request.defaults.headers["token"] = data.token.value;
|
||||
return request.post('/cid/log', params, {
|
||||
let request1 = getRequest();
|
||||
let token = data.token;
|
||||
const { token: _, ...requestData } = data;
|
||||
return request1.post('/cid/log', requestData, {
|
||||
headers: {
|
||||
'token': data.token, // 将 token 替换为您的令牌值
|
||||
'token': token, // 将 token 替换为您的令牌值
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
function getRequest() {
|
||||
let server = localStorage.getItem('cid_server');
|
||||
let request1 = null;
|
||||
if (server === "tx.ljsea.top") {
|
||||
request1 = request;
|
||||
} else if (server === "js.ljsea.top") {
|
||||
request1 = request_aliyun;
|
||||
}else{
|
||||
console.log("Using custom server:", server);
|
||||
request1 = createRequestInstance("https://"+server)
|
||||
}
|
||||
return request1;
|
||||
}
|
||||
|
||||
export function getCIDRuningListService(data) {
|
||||
let request1 = getRequest();
|
||||
let path = '/cid/running?type=' + data.type;
|
||||
|
||||
return request1.get(path, {
|
||||
headers: {
|
||||
'token': data.token, // 将 token 替换为您的令牌值
|
||||
}
|
||||
})
|
||||
}
|
||||
|
|
@ -1,45 +1,50 @@
|
|||
import request from '@/utils/request.js'
|
||||
import request2 from '@/utils/gs_req.js';
|
||||
|
||||
export const restartDeviceService = (data) => {
|
||||
const params = new URLSearchParams();
|
||||
for (let key in data) {
|
||||
if(key == "token") continue;
|
||||
params.append(key, data[key])
|
||||
}
|
||||
return request.post('/device/restart', params, { "headers": { 'token': data.token } });
|
||||
return request2.post('/device/restart', params, { "headers": { 'token': data.token } });
|
||||
}
|
||||
|
||||
export const updateDeviceService = (data) => {
|
||||
const params = new URLSearchParams();
|
||||
for (let key in data) {
|
||||
if(key == "token") continue;
|
||||
params.append(key, data[key])
|
||||
}
|
||||
return request.post('/device/update_device', params, { "headers": { 'token': data.token } });
|
||||
return request2.post('/device/update_device', params, { "headers": { 'token': data.token } });
|
||||
}
|
||||
|
||||
export const deleteDeviceService = (data) => {
|
||||
const params = new URLSearchParams();
|
||||
for (let key in data) {
|
||||
if(key == "token") continue;
|
||||
params.append(key, data[key])
|
||||
}
|
||||
return request.post('/device/delete_device', params, { "headers": { 'token': data.token } });
|
||||
return request2.post('/device/delete_device', params, { "headers": { 'token': data.token } });
|
||||
}
|
||||
|
||||
export const addDeviceService = (data) => {
|
||||
const params = new URLSearchParams();
|
||||
for (let key in data) {
|
||||
if(key == "token") continue;
|
||||
params.append(key, data[key])
|
||||
}
|
||||
return request.post('/device/add_device', params, { "headers": { 'token': data.token },'Content-Type': 'application/json' });
|
||||
return request2.post('/device/add_device', params, { "headers": { 'token': data.token },'Content-Type': 'application/json' });
|
||||
}
|
||||
|
||||
export const getDeviceListService = (data) => {
|
||||
const params = new URLSearchParams();
|
||||
for (let d in data) {
|
||||
if(d == "token") continue;
|
||||
params.append(d, data[d]);
|
||||
}
|
||||
// request.headers["Content-Type"] = "application/json";
|
||||
request.defaults.headers["token"] = data.token.value;
|
||||
return request.post('/device/get_device_list', params, {
|
||||
request2.defaults.headers["token"] = data.token.value;
|
||||
return request2.post('/device/get_device_list', params, {
|
||||
headers: {
|
||||
'token': data.token, // 将 token 替换为您的令牌值
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,71 @@
|
|||
import request from '@/utils/request.js'
|
||||
import { createRequestInstance } from '@/utils/req_base.js';
|
||||
import request_aliyun from '@/utils/aliyun_erver.js';
|
||||
|
||||
|
||||
export const updateConfigFileService = (data) => {
|
||||
let params={};
|
||||
for (let key in data) {
|
||||
if (key === 'token') continue;
|
||||
params[key] = data[key];
|
||||
}
|
||||
let request1 = getRequest();
|
||||
return request1.post('/file/config_update', params, { "headers": { 'token': data.token } });
|
||||
}
|
||||
|
||||
export const deleteConfigFileService = (data) => {
|
||||
let request1 = getRequest();
|
||||
return request1.post('/file/config_delete', data, { "headers": { 'token': data.token } });
|
||||
}
|
||||
|
||||
export const addConfigFileService = (data) => {
|
||||
let params={};
|
||||
for (let key in data) {
|
||||
if (key === 'token') continue;
|
||||
params[key] = data[key];
|
||||
}
|
||||
let request1 = getRequest();
|
||||
return request1.post('/file/config_add', params, { "headers": { 'token': data.token },'Content-Type': 'application/json' });
|
||||
}
|
||||
|
||||
export const getConfigFileListService = (data) => {
|
||||
let params={};
|
||||
for (let key in data) {
|
||||
if (key === 'token') continue;
|
||||
params[key] = data[key];
|
||||
}
|
||||
// request.headers["Content-Type"] = "application/json
|
||||
let request1 = getRequest();
|
||||
request1.defaults.headers["token"] = data.token.value;
|
||||
return request1.post('/file/config_search', params, {
|
||||
headers: {
|
||||
'token': data.token, // 将 token 替换为您的令牌值
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
// function getRequest() {
|
||||
// let server = localStorage.getItem('config_file_server');
|
||||
// let request1 = null;
|
||||
// if (server === "tx.ljsea.top") {
|
||||
// request1 = request;
|
||||
// } else {
|
||||
// request1 = request2;
|
||||
// }
|
||||
// return request1;
|
||||
// }
|
||||
|
||||
function getRequest() {
|
||||
let server = localStorage.getItem('config_file_server');
|
||||
let request1 = null;
|
||||
if (server === "tx.ljsea.top") {
|
||||
request1 = request;
|
||||
} else if (server === "js.ljsea.top") {
|
||||
request1 = request_aliyun;
|
||||
}else{
|
||||
console.log("Using custom server:", server);
|
||||
request1 = createRequestInstance("https://"+server)
|
||||
}
|
||||
return request1;
|
||||
}
|
||||
|
|
@ -0,0 +1,62 @@
|
|||
import request from '@/utils/request.js'
|
||||
|
||||
|
||||
|
||||
export const deleteGroupService = (data) => {
|
||||
const params = new URLSearchParams();
|
||||
for (let key in data) {
|
||||
if(key == "token") continue;
|
||||
params.append(key, data[key])
|
||||
}
|
||||
return request.post('/device/delete_device', params, { "headers": { 'token': data.token } });
|
||||
}
|
||||
|
||||
export const updateGroupService = (data) => {
|
||||
const params = new URLSearchParams();
|
||||
for (let key in data) {
|
||||
if(key == "token") continue;
|
||||
params.append(key, data[key])
|
||||
}
|
||||
return request.post('/im/update_group', params, { "headers": { 'token': data.token } });
|
||||
}
|
||||
|
||||
export const addDeviceService = (data) => {
|
||||
const params = new URLSearchParams();
|
||||
for (let key in data) {
|
||||
if(key == "token") continue;
|
||||
params.append(key, data[key])
|
||||
}
|
||||
return request.post('/device/add_device', params, { "headers": { 'token': data.token },'Content-Type': 'application/json' });
|
||||
}
|
||||
|
||||
export const getGroupListService = (data) => {
|
||||
const params = new URLSearchParams();
|
||||
for (let d in data) {
|
||||
if(d == "token") continue;
|
||||
params.append(d, data[d]);
|
||||
}
|
||||
// request.headers["Content-Type"] = "application/json";
|
||||
request.defaults.headers["token"] = data.token.value;
|
||||
return request.post('/im/get_group', params, {
|
||||
headers: {
|
||||
'token': data.token, // 将 token 替换为您的令牌值
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
export const getGroupReqService = (data) => {
|
||||
const params = new URLSearchParams();
|
||||
for (let d in data) {
|
||||
if(d == "token") continue;
|
||||
params.append(d, data[d]);
|
||||
}
|
||||
// request.headers["Content-Type"] = "application/json";
|
||||
request.defaults.headers["token"] = data.token.value;
|
||||
return request.post('/im/get_group', params, {
|
||||
headers: {
|
||||
'token': data.token, // 将 token 替换为您的令牌值
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
|
|
@ -3,6 +3,7 @@ import request from '@/utils/request.js'
|
|||
export const getImKeyService = (Data) => {
|
||||
const params = new URLSearchParams();
|
||||
for (let key in Data) {
|
||||
if(key == "token") continue;
|
||||
params.append(key, Data[key])
|
||||
}
|
||||
return request.post('/im/get_imKey', params,{
|
||||
|
|
|
|||
|
|
@ -0,0 +1,45 @@
|
|||
import request from '@/utils/request.js'
|
||||
|
||||
|
||||
|
||||
export const updateConfigShellService = (data) => {
|
||||
const params = new URLSearchParams();
|
||||
const jsonString = encodeURIComponent(JSON.stringify(data));
|
||||
params.append('data', jsonString);
|
||||
return request.post('/shell/update', params, { "headers": { 'token': data.token } });
|
||||
}
|
||||
|
||||
export const deleteConfigShellService = (data) => {
|
||||
let reqData={
|
||||
"shells": data.shells,
|
||||
}
|
||||
return request.post('/shell/delete', reqData, { "headers": { 'token': data.token } });
|
||||
}
|
||||
|
||||
export const addConfigShellService = (data) => {
|
||||
const params = new URLSearchParams();
|
||||
for (let key in data) {
|
||||
if(key === 'token'){
|
||||
continue;
|
||||
}
|
||||
params.append(key, data[key])
|
||||
}
|
||||
return request.post('/shell/create', params, { "headers": { 'token': data.token },'Content-Type': 'application/json' });
|
||||
}
|
||||
|
||||
export const getConfigShellListService = (data) => {
|
||||
const params = new URLSearchParams();
|
||||
for (let d in data) {
|
||||
if(d == "token") continue;
|
||||
params.append(d, data[d]);
|
||||
}
|
||||
// request.headers["Content-Type"] = "application/json
|
||||
let request1 = request;
|
||||
request1.defaults.headers["token"] = data.token.value;
|
||||
return request1.post('/shell/list', params, {
|
||||
headers: {
|
||||
'token': data.token, // 将 token 替换为您的令牌值
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
|
|
@ -0,0 +1,71 @@
|
|||
import request from '@/utils/request.js'
|
||||
import request2 from '@/utils/gs_req.js';
|
||||
|
||||
|
||||
export const GetRedisInfoService = (Data) => {
|
||||
const params = new URLSearchParams();
|
||||
for (let key in Data) {
|
||||
if(key == "token") continue;
|
||||
params.append(key, Data[key])
|
||||
}
|
||||
let request1 = getRequest();
|
||||
return request1.post('/tool/get_redis', params,{
|
||||
headers: {
|
||||
'token': Data.token, // 闂佽绻愭蹇涘箯閿燂拷 token 闂備礁鎼ú锔锯偓绗涘啰鏆﹂柛娆忣槺閳绘棃鏌i幋鐏活亝绂嶉崼鏇熺厽闁靛ǹ鍎遍褔鏌熼煬鎻掆偓婵嬪箖瑜忔禒锔炬喆閿濆懍澹曢梺璺ㄥ櫐閹凤拷
|
||||
}
|
||||
})
|
||||
}
|
||||
function getRequest() {
|
||||
let server = localStorage.getItem('cid_server');
|
||||
let request1 = null;
|
||||
if (server === "tx.ljsea.top") {
|
||||
request1 = request;
|
||||
} else {
|
||||
request1 = request2;
|
||||
}
|
||||
return request1;
|
||||
}
|
||||
|
||||
export const UploadFileService = (formData,token) => {
|
||||
//let request1 = getRequest();
|
||||
return request.post('/tool/upload', formData,{
|
||||
headers: {
|
||||
'Content-Type': 'multipart/form-data',
|
||||
'token': token,
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
export const GetFileInfoByMd5Service = (Data) => {
|
||||
const params = new URLSearchParams();
|
||||
for (let key in Data) {
|
||||
if(key == "token") continue;
|
||||
params.append(key, Data[key])
|
||||
}
|
||||
//let request1 = getRequest();
|
||||
return request.post('/tool/file_list', params,{
|
||||
headers: {
|
||||
'token': Data.token,
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
export const GetMonitorDeviceInfoService = (Data) => {
|
||||
return request.get('/tool/get_monitor_list')
|
||||
}
|
||||
|
||||
export const UpdateMonitorDeviceInfoService = (Data) => {
|
||||
return request.post('/tool/update_monitor', Data,{
|
||||
headers: {
|
||||
'token': Data.token, // 闂佽绻愭蹇涘箯閿燂拷 token 闂備礁鎼ú锔锯偓绗涘啰鏆﹂柛娆忣槺閳绘棃鏌i幋鐏活亝绂嶉崼鏇熺厽闁靛ǹ鍎遍褔鏌熼煬鎻掆偓婵嬪箖瑜忔禒锔炬喆閿濆懍澹曢梺璺ㄥ櫐閹凤拷
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
export const DelMonitorDeviceInfoService = (Data) => {
|
||||
return request.post('/tool/del_monitor', Data,{
|
||||
headers: {
|
||||
'token': Data.token, // 闂佽绻愭蹇涘箯閿燂拷 token 闂備礁鎼ú锔锯偓绗涘啰鏆﹂柛娆忣槺閳绘棃鏌i幋鐏活亝绂嶉崼鏇熺厽闁靛ǹ鍎遍褔鏌熼煬鎻掆偓婵嬪箖瑜忔禒锔炬喆閿濆懍澹曢梺璺ㄥ櫐閹凤拷
|
||||
}
|
||||
})
|
||||
}
|
||||
114
src/api/user.js
114
src/api/user.js
|
|
@ -1,4 +1,4 @@
|
|||
import request from '@/utils/request.js'
|
||||
import request from '@/utils/uc_req.js';
|
||||
import md5 from 'js-md5';
|
||||
|
||||
export const loginService = (loginData) => {
|
||||
|
|
@ -6,7 +6,7 @@ export const loginService = (loginData) => {
|
|||
loginData = loginData._value;
|
||||
for (let key in loginData) {
|
||||
if (key === "username") {
|
||||
//正则表达式判断邮箱
|
||||
//濮濓絽鍨悰銊ㄦ彧瀵繐鍨介弬顓㈠仏缁狅拷
|
||||
if (RegExp(/^[a-zA-Z0-9_-]+@[a-zA-Z0-9_-]+(\.[a-zA-Z0-9_-]+)+$/).test(loginData[key])) {
|
||||
loginData['email'] = loginData[key]
|
||||
loginData[key] = ''
|
||||
|
|
@ -40,14 +40,122 @@ export const getUUIDService = (registerData) => {
|
|||
return request.post('/user/uuid', params)
|
||||
}
|
||||
|
||||
export const addGroupRequestService = (Data) => {
|
||||
const params = new URLSearchParams();
|
||||
for (let key in Data) {
|
||||
if(key == "token") continue;
|
||||
params.append(key, Data[key])
|
||||
}
|
||||
return request.post('/im/send_message', params,{
|
||||
headers: {
|
||||
'token': Data.token, // 鐏忥拷 token 閺囨寧宕叉稉鐑樺亶閻ㄥ嫪鎶ら悧灞解偓锟<E58193>
|
||||
}
|
||||
})
|
||||
}
|
||||
export const getFriendReqService = (Data) => {
|
||||
const params = new URLSearchParams();
|
||||
for (let key in Data) {
|
||||
if(key == "token") continue;
|
||||
params.append(key, Data[key])
|
||||
}
|
||||
return request.post('/im/get_friend_request', params, {
|
||||
headers: {
|
||||
'token': Data.token, // 鐏忥拷 token 閺囨寧宕叉稉鐑樺亶閻ㄥ嫪鎶ら悧灞解偓锟<E58193>
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
export const GetUserInfoService = (Data) => {
|
||||
const params = new URLSearchParams();
|
||||
for (let key in Data) {
|
||||
if(key == "token") continue;
|
||||
params.append(key, Data[key])
|
||||
}
|
||||
return request.post('/user/info', params, {
|
||||
headers: {
|
||||
'Authorization': "Bearer " + Data.token ,
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
//閸掔娀娅庢總钘夊几閹存牞鈧懐鍏㈢紒锟<E7B492>
|
||||
export const DelFGService =(Data) =>{
|
||||
const params = new URLSearchParams();
|
||||
for (let key in Data) {
|
||||
if(key == "token") continue;
|
||||
params.append(key, Data[key])
|
||||
}
|
||||
return request.post('/im/del_friend_or_group', params, {
|
||||
headers: {
|
||||
'token': Data.token, // 鐏忥拷 token 閺囨寧宕叉稉鐑樺亶閻ㄥ嫪鎶ら悧灞解偓锟<E58193>
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
export const updateUserInfoService = (Data) => {
|
||||
const params = new URLSearchParams();
|
||||
for (let key in Data) {
|
||||
if(key == "token") continue;
|
||||
params.append(key, Data[key])
|
||||
}
|
||||
return request.post('/user/update', params, {
|
||||
headers: {
|
||||
'token': Data.token, // 鐏忥拷 token 閿熸枻鎷烽幑顫礋閹劎娈戞禒銈囧閸婏拷
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
export const acceptInviteService =(Data)=> {
|
||||
const params = new URLSearchParams();
|
||||
for (let key in Data) {
|
||||
if(key == "token") continue;
|
||||
params.append(key, Data[key])
|
||||
}
|
||||
return request.post('/im/accept_invite', params, {
|
||||
headers: {
|
||||
'token': Data.token, // 鐏忥拷 token 閺囨寧宕叉稉鐑樺亶閻ㄥ嫪鎶ら悧灞解偓锟<E58193>
|
||||
}
|
||||
})
|
||||
}
|
||||
export const rejectInviteService =(Data)=> {
|
||||
const params = new URLSearchParams();
|
||||
for (let key in Data) {
|
||||
if(key == "token") continue;
|
||||
params.append(key, Data[key])
|
||||
}
|
||||
return request.post('/im/reject_invite', params, {
|
||||
headers: {
|
||||
'token': Data.token, // 鐏忥拷 token 閺囨寧宕叉稉鐑樺亶閻ㄥ嫪鎶ら悧灞解偓锟<E58193>
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
export const SearchUserService = (Data) => {
|
||||
const params = new URLSearchParams();
|
||||
for (let key in Data) {
|
||||
if(key == "token") continue;
|
||||
params.append(key, Data[key])
|
||||
}
|
||||
return request.post('/user/search', params,{
|
||||
headers: {
|
||||
'token': Data.token, // 将 token 替换为您的令牌值
|
||||
'token': Data.token, // 鐏忥拷 token 閺囨寧宕叉稉鐑樺亶閻ㄥ嫪鎶ら悧灞解偓锟<E58193>
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
export const getUserTokenCode = (Data) => {
|
||||
return request.get('/user/get_token_code', {
|
||||
headers: {
|
||||
'Authorization': `Bearer ${Data.token}`, // 使用 Bearer 认证方式
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
export const getTokenByCode = (Data) => {
|
||||
let url = '/user/get_token_by_code' + "?code=" + Data.code
|
||||
return request.get(url, {
|
||||
headers: {
|
||||
'Authorization': `Bearer ${Data.token}`, // 使用 Bearer 认证方式
|
||||
}
|
||||
})
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,18 +1,29 @@
|
|||
import request from '@/utils/request.js'
|
||||
import request2 from '@/utils/gs_req.js';
|
||||
|
||||
export const playVideoService = (data) => {
|
||||
const params = new URLSearchParams();
|
||||
for (let key in data) {
|
||||
if(key == "token") continue;
|
||||
params.append(key, data[key])
|
||||
}
|
||||
return request.post('/video', params, Headers = { 'Accept': 'application/vnd.apple.mpegurl','token': data.token });
|
||||
return request2.post('/video', params, Headers = { 'Accept': 'application/vnd.apple.mpegurl','token': data.token });
|
||||
}
|
||||
export const delayVideoService = (data) => {
|
||||
const params = new URLSearchParams();
|
||||
for (let key in data) {
|
||||
if(key == "token") continue;
|
||||
params.append(key, data[key])
|
||||
}
|
||||
return request.post('/video/delay', params, { headers : {'token': data.token }});
|
||||
return request2.post('/video/delay', params, { headers : {'token': data.token }});
|
||||
}
|
||||
|
||||
export const deleteVideoService = (data) => {
|
||||
const params = new URLSearchParams();
|
||||
for (let key in data) {
|
||||
if(key == "token") continue;
|
||||
params.append(key, data[key])
|
||||
}
|
||||
return request2.post('/video/delete', params, { headers : {'token': data.token }});
|
||||
}
|
||||
|
||||
export const quashVideoService = (data) => {
|
||||
|
|
@ -20,7 +31,20 @@ export const quashVideoService = (data) => {
|
|||
for (let key in data) {
|
||||
params.append(key, data[key])
|
||||
}
|
||||
return request.post('/video/quash_option', params, { headers : {'token': data.token }});
|
||||
return request2.post('/video/quash_option', params, { headers : {'token': data.token }});
|
||||
}
|
||||
function getTimeString(time) {
|
||||
let date = new Date(time);
|
||||
// 提取年、月、日、时、分、秒
|
||||
const year = date.getFullYear();
|
||||
const month = (''+(date.getMonth() + 1)).slice(-2); // 月份是从0开始的,所以要加1
|
||||
const day = ('0' + date.getDate()).slice(-2);
|
||||
const hour = ('0' + date.getHours()).slice(-2);
|
||||
const minute = ('0' + date.getMinutes()).slice(-2);
|
||||
const second = ('0' + date.getSeconds()).slice(-2);
|
||||
|
||||
// 重新组合并返回格式化的日期时间字符串
|
||||
return `${year}/${month}/${day} ${hour}:${minute}:${second}`;
|
||||
}
|
||||
|
||||
export const getVideoListService = (data) => {
|
||||
|
|
@ -29,16 +53,29 @@ export const getVideoListService = (data) => {
|
|||
for (let key in data) {
|
||||
if (key === 'entrydate' && data[key].length > 0) {
|
||||
if (hour === "33") {
|
||||
let begin = data[key][0].toLocaleString().slice(0, 10) + " 00:00:00"; //begin=data[key][0].toLocaleString().slice(0,10)+hour+":00:00";
|
||||
params.append("begin", begin);
|
||||
let end = data[key][1].toLocaleString().slice(0, 10) + " 23:59:59";
|
||||
params.append("end", end);
|
||||
let b1=Date.parse(data[key][0]);
|
||||
let b2=Date.parse(data[key][1]);
|
||||
let begin = getTimeString(b1).toString().slice(0, 10) + " 00:00:00"; //begin=data[key][0].toLocaleString().slice(0,10)+hour+":00:00";
|
||||
|
||||
//alert(begin)
|
||||
let end = getTimeString(b2).toString().slice(0, 10) + " 23:59:59";
|
||||
//转为时间戳
|
||||
let end_date = Date.parse(end)/1000;
|
||||
let begin_date = Date.parse(begin)/1000;
|
||||
params.append("begin", begin_date);
|
||||
params.append("end", end_date);
|
||||
continue;
|
||||
} else {
|
||||
let begin = data[key][0].toLocaleString().slice(0, 10) + hour + ":00:00"; //begin=data[key][0].toLocaleString().slice(0,10)+hour+":00:00";
|
||||
params.append("begin", begin);
|
||||
let end = data[key][1].toLocaleString().slice(0, 10) + hour + ":59:59";
|
||||
params.append("end", end);
|
||||
let b1=Date.parse(data[key][0]);
|
||||
let b2=Date.parse(data[key][1]);
|
||||
let begin = getTimeString(b1).toString().slice(0, 10) + " "+hour + ":00:00"; //begin=data[key][0].toLocaleString().slice(0,10)+hour+":00:00";
|
||||
//params.append("begin", begin);
|
||||
let end = getTimeString(b2).toString().slice(0, 10) + " "+hour + ":59:59";
|
||||
console.log("begin:",begin);
|
||||
let end_date = Date.parse(end)/1000;
|
||||
let begin_date = Date.parse(begin)/1000;
|
||||
params.append("begin", begin_date);
|
||||
params.append("end", end_date);
|
||||
continue;
|
||||
}
|
||||
|
||||
|
|
@ -46,8 +83,8 @@ export const getVideoListService = (data) => {
|
|||
params.append(key, data[key])
|
||||
}
|
||||
// request.headers["Content-Type"] = "application/json";
|
||||
request.defaults.headers["token"] = data.token.value;
|
||||
return request.post('/video/get_video_list', params, {
|
||||
request2.defaults.headers["token"] = data.token.value;
|
||||
return request2.post('/video/get_video_list', params, {
|
||||
headers: {
|
||||
'token': data.token, // 将 token 替换为您的令牌值
|
||||
}
|
||||
|
|
|
|||
Binary file not shown.
|
After Width: | Height: | Size: 8.7 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 6.0 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 69 KiB |
|
|
@ -0,0 +1 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 144.08 128.61"><title>资源 82</title><path d="M72.23 128.61c-7.1-.23-11.51-3.72-14.76-9.36C48 102.87 38.43 86.59 29.1 70.16a36 36 0 0 1-4.47-11.35A14.61 14.61 0 0 1 34 42.51c7.49-2.71 15.71-.21 19.67 6.43 7.52 12.56 14.77 25.27 22.12 37.92 3 5.17 5.89 10.43 9 15.51 5 8 3.45 18-4.22 23.31-2.3 1.62-5.52 1.99-8.34 2.93z" fill="#2ef2e9"/><path d="M72.66.33c6-.57 10.39 2.6 13.51 8C95.61 24.69 105 41.1 114.52 57.4c3.9 6.65-.28 17.13-6.39 20.44-8.93 4.83-17.88 1.28-21.86-5.62C76.82 55.86 67.14 39.62 58.11 23 52.06 12 59.61.24 72.66.33z" fill="#fa6663"/><path d="M144.08 15.83c-.58 8.62-6.73 15.57-15.51 15.66-9.31.09-16.87-7-16.95-15.62S119 0 127.87 0c9.13.09 16.22 7 16.21 15.83z" fill="#fbb355"/><path d="M16.24 31.5C7 31.33-.19 24.42 0 15.8.19 7.5 7.19-.06 14.64 0c10.53.08 18.27 6.73 17.61 15.9-.64 8.96-6.25 15.28-16.01 15.6z" fill="#8a56c2"/></svg>
|
||||
|
After Width: | Height: | Size: 918 B |
Binary file not shown.
|
After Width: | Height: | Size: 37 KiB |
|
|
@ -6,8 +6,12 @@ import 'element-plus/dist/index.css'
|
|||
import App from './App.vue'
|
||||
import router from '@/router'
|
||||
import globalData from '@/utils/global.js'
|
||||
import Menu from '@/views/Menu.vue'
|
||||
// import VideoPlayer from '@/views/Video.vue'
|
||||
|
||||
const app=createApp(App);
|
||||
app.component('Menu',Menu);
|
||||
// app.component('VideoPlayer',VideoPlayer);
|
||||
app.provide('globalData',globalData);
|
||||
|
||||
app.use(router).use(ElementPlus).mount('#app');
|
||||
|
|
|
|||
|
|
@ -9,6 +9,14 @@ import ImVue from "@/views/Im.vue";
|
|||
import CIDListVue from "@/views/CIDList.vue";
|
||||
import CIDLog from "@/views/CIDLog.vue";
|
||||
import DeviceRealVP from "@/views/DeviceRealVP.vue";
|
||||
import Chat from "@/views/Chat.vue"
|
||||
import Group from "@/views/Group.vue"
|
||||
import File from "@/views/FileList.vue"
|
||||
import Shell from "@/views/ShellList.vue"
|
||||
|
||||
import callback from "@/views/callback.vue";
|
||||
import projectSelect from "@/views/project-select.vue";
|
||||
|
||||
|
||||
const routes = [
|
||||
{
|
||||
|
|
@ -51,11 +59,41 @@ const routes = [
|
|||
name: 'CID',
|
||||
component: CIDListVue
|
||||
},
|
||||
{
|
||||
path: "/group",
|
||||
name: "Group",
|
||||
component: Group
|
||||
},
|
||||
{
|
||||
path: '/cidlog',
|
||||
name: 'CIDLog',
|
||||
component: CIDLog
|
||||
},
|
||||
{
|
||||
path:"/chat",
|
||||
name:"chat",
|
||||
component:Chat
|
||||
},
|
||||
{
|
||||
path:"/file",
|
||||
name:"file",
|
||||
component:File
|
||||
},
|
||||
{
|
||||
path:"/shell",
|
||||
name:"shell",
|
||||
component:Shell
|
||||
},
|
||||
{
|
||||
path: '/callback',
|
||||
name: 'callback',
|
||||
component: callback
|
||||
},
|
||||
{
|
||||
path: '/projectSelect',
|
||||
name: 'projectSelect',
|
||||
component: projectSelect
|
||||
},
|
||||
{
|
||||
path: '/',
|
||||
redirect: '/login'
|
||||
|
|
|
|||
|
|
@ -0,0 +1,46 @@
|
|||
import axios from "axios";
|
||||
import router from "@/router/index.js";
|
||||
import { ElMessage } from 'element-plus';
|
||||
//const baseURL = "https://gep.ljsea.xyz/";
|
||||
//const baseURL= "http://localhost:8083";
|
||||
//const baseURL="https://pm.ljsea.top";
|
||||
const baseURL2 = "https://js.ljsea.top/";
|
||||
const request_aliyun = axios.create({
|
||||
baseURL: baseURL2,
|
||||
});
|
||||
|
||||
|
||||
|
||||
request_aliyun.interceptors.response.use(
|
||||
result => {
|
||||
if(result.status!==200 ){
|
||||
router.push("/login")
|
||||
}
|
||||
if(result.data.message==="NOT_LOGIN"|| [2, 3, 4].includes(result.data.code)){
|
||||
//alert("登录失效,请重新登录!")
|
||||
ElMessage.error('登录失效,请重新登录!');
|
||||
localStorage.removeItem("token");
|
||||
router.push("/login")
|
||||
return
|
||||
}
|
||||
if(result.data.code == 7){
|
||||
//alert("该用户已存在,请重新输入!");
|
||||
ElMessage.error('该用户已存在,请重新输入!');
|
||||
return null
|
||||
}
|
||||
|
||||
if(result.data.code == 1){
|
||||
//alert("请求失败,请稍后重试!");
|
||||
ElMessage.error('请求失败,请稍后重试!');
|
||||
}else{
|
||||
return result.data
|
||||
}
|
||||
},
|
||||
error => {
|
||||
//alert("请求失败,请稍后重试!");
|
||||
ElMessage.error('请求失败,请稍后重试!');
|
||||
return Promise.reject(error);
|
||||
}
|
||||
)
|
||||
|
||||
export default request_aliyun;
|
||||
|
|
@ -0,0 +1,93 @@
|
|||
import axios from "axios";
|
||||
import router from "@/router/index.js";
|
||||
import { ElMessage } from 'element-plus';
|
||||
//const baseURL = "https://gep.ljsea.xyz/";
|
||||
//const baseURL= "http://localhost:8083";
|
||||
//const baseURL="https://pm.ljsea.top";
|
||||
const baseURL = "https://gep.ljsea.top/";
|
||||
|
||||
|
||||
let isRefreshing = false;
|
||||
let requests = [];
|
||||
|
||||
const request = axios.create({
|
||||
baseURL: baseURL,
|
||||
});
|
||||
|
||||
// 请求拦截器 - 添加token
|
||||
request.interceptors.request.use(
|
||||
config => {
|
||||
const token = localStorage.getItem("token");
|
||||
if (token) {
|
||||
config.headers.Authorization = `Bearer ${token}`;
|
||||
config.headers.token = token;
|
||||
}
|
||||
return config;
|
||||
}
|
||||
);
|
||||
|
||||
// 响应拦截器
|
||||
request.interceptors.response.use(
|
||||
result => {
|
||||
if(result.status !== 200) {
|
||||
router.push("/login");
|
||||
}
|
||||
|
||||
if(result.data.message === "NOT_LOGIN" || [2, 3, 4].includes(result.data.code)) {
|
||||
// 检测到token过期
|
||||
if (isRefreshing == false) {
|
||||
isRefreshing = true;
|
||||
// 这里需要替换为实际的refresh token请求
|
||||
return axios.post('https://uc.ljsea.top/user/refresh_token', {
|
||||
refresh_token: localStorage.getItem("refresh_token")
|
||||
},{
|
||||
headers: {
|
||||
'Authorization': `Bearer ${localStorage.getItem("refresh_token")}`
|
||||
}
|
||||
}).then(res => {
|
||||
const token = res.data["data"]["access_token"];
|
||||
localStorage.setItem("token", token);
|
||||
//alert("token: " + token);
|
||||
|
||||
// 重试所有挂起的请求
|
||||
requests.forEach(cb => cb(token));
|
||||
requests = [];
|
||||
isRefreshing = false;
|
||||
|
||||
// 重试当前请求
|
||||
const config = result.config;
|
||||
config.headers.Authorization = `Bearer ${token}`;
|
||||
return request(config);
|
||||
}).catch(err => {
|
||||
// 刷新token失败,跳转登录
|
||||
ElMessage.error('登录已过期,请重新登录!');
|
||||
router.push("/login");
|
||||
return Promise.reject(err);
|
||||
});
|
||||
} else if (isRefreshing) {
|
||||
// 正在刷新token,将请求放入队列
|
||||
return new Promise(resolve => {
|
||||
requests.push(token => {
|
||||
//alert("new token: " + token);
|
||||
result.config.headers.Authorization = `Bearer ${token}`;
|
||||
result.config.headers.token = token;
|
||||
resolve(request(result.config));
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
if(result.data.code == 7) {
|
||||
ElMessage.error('该用户已存在,请重新输入!');
|
||||
return null;
|
||||
}
|
||||
|
||||
if(result.data.code == 1) {
|
||||
ElMessage.error('请求失败,请稍后重试!');
|
||||
} else {
|
||||
return result.data;
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
export default request;
|
||||
|
|
@ -0,0 +1,99 @@
|
|||
import axios from "axios";
|
||||
import router from "@/router/index.js";
|
||||
import { ElMessage } from 'element-plus';
|
||||
let isRefreshing = false;
|
||||
let requests = [];
|
||||
|
||||
// 错误处理函数
|
||||
const handleResponseError = (result) => {
|
||||
if (result.status !== 200) {
|
||||
router.push("/login");
|
||||
}
|
||||
if (result.data.message === "NOT_LOGIN" || [2, 3, 4].includes(result.data.code)) {
|
||||
// 检测到token过期
|
||||
if (isRefreshing == false) {
|
||||
isRefreshing = true;
|
||||
|
||||
// 这里需要替换为实际的refresh token请求
|
||||
return axios.post('https://uc.ljsea.top/user/refresh_token', {
|
||||
refresh_token: localStorage.getItem("refresh_token")
|
||||
},{
|
||||
headers: {
|
||||
'Authorization': `Bearer ${localStorage.getItem("refresh_token")}`
|
||||
}
|
||||
}).then(res => {
|
||||
const token = res.data["data"]["access_token"];
|
||||
localStorage.setItem("token", token);
|
||||
|
||||
// 重试所有挂起的请求
|
||||
requests.forEach(cb => cb(token));
|
||||
requests = [];
|
||||
isRefreshing = false;
|
||||
|
||||
// 重试当前请求
|
||||
const config = result.config;
|
||||
config.headers.Authorization = `Bearer ${token}`;
|
||||
return request(config);
|
||||
}).catch(err => {
|
||||
// 刷新token失败,跳转登录
|
||||
ElMessage.error('登录已过期,请重新登录!');
|
||||
router.push("/login");
|
||||
return Promise.reject(err);
|
||||
});
|
||||
} else if (isRefreshing) {
|
||||
// 正在刷新token,将请求放入队列
|
||||
return new Promise(resolve => {
|
||||
requests.push(token => {
|
||||
result.config.headers.Authorization = `Bearer ${token}`;
|
||||
resolve(request(result.config));
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
if (result.data.code === 7) {
|
||||
ElMessage.error('该用户已存在,请重新输入!');
|
||||
return null;
|
||||
}
|
||||
if (result.data.code === 1) {
|
||||
ElMessage.error('请求失败,请稍后重试!');
|
||||
}
|
||||
return result.data;
|
||||
};
|
||||
|
||||
// 请求实例缓存
|
||||
const instances = new Map();
|
||||
|
||||
// 请求工厂函数(单例模式)
|
||||
export const createRequestInstance = (baseURL, config = {}) => {
|
||||
// 检查是否已存在该域名的实例
|
||||
if (instances.has(baseURL)) {
|
||||
return instances.get(baseURL);
|
||||
}
|
||||
|
||||
// 创建新实例
|
||||
const instance = axios.create({
|
||||
baseURL,
|
||||
timeout: 10000, // 默认超时时间
|
||||
headers: {
|
||||
'Content-Type': 'application/json'
|
||||
},
|
||||
...config
|
||||
});
|
||||
|
||||
// 添加响应拦截器
|
||||
instance.interceptors.response.use(
|
||||
result => handleResponseError(result),
|
||||
error => {
|
||||
ElMessage.error('请求失败,请稍后重试!');
|
||||
return Promise.reject(error);
|
||||
}
|
||||
);
|
||||
|
||||
// 缓存实例
|
||||
instances.set(baseURL, instance);
|
||||
|
||||
return instance;
|
||||
};
|
||||
|
||||
// 默认导出原有的阿里云请求实例
|
||||
export default createRequestInstance("https://tx.ljsea.top/");
|
||||
|
|
@ -1,39 +1,94 @@
|
|||
import axios from "axios";
|
||||
import router from "@/router/index.js";
|
||||
const baseURL = "https://gep.ljsea.xyz/";
|
||||
//const baseURL= "http://localhost:8082";
|
||||
import { ElMessage } from 'element-plus';
|
||||
//const baseURL = "https://gep.ljsea.top/";
|
||||
const baseURL = "https://tx.ljsea.top/";
|
||||
//const baseURL= "http://localhost:8083";
|
||||
//const baseURL="https://pm.ljsea.top";
|
||||
//const baseURL = "https://gep.ljsea.xyz/";
|
||||
|
||||
|
||||
let isRefreshing = false;
|
||||
let requests = [];
|
||||
|
||||
const request = axios.create({
|
||||
baseURL: baseURL,
|
||||
});
|
||||
|
||||
// 请求拦截器 - 添加token
|
||||
request.interceptors.request.use(
|
||||
config => {
|
||||
const token = localStorage.getItem("token");
|
||||
if (token) {
|
||||
config.headers.Authorization = `Bearer ${token}`;
|
||||
config.headers.token = token;
|
||||
}
|
||||
return config;
|
||||
}
|
||||
);
|
||||
|
||||
// 响应拦截器
|
||||
request.interceptors.response.use(
|
||||
result => {
|
||||
if(result.status !== 200) {
|
||||
router.push("/login")
|
||||
router.push("/login");
|
||||
}
|
||||
if(result.data.message==="NOT_LOGIN"||result.data.code==2 || result.data.code ===3 ||result.data.code ===4){
|
||||
alert("登录失效,请重新登录!")
|
||||
localStorage.removeItem("token");
|
||||
router.push("/login")
|
||||
return
|
||||
|
||||
if(result.data.message === "NOT_LOGIN" || [2, 3, 4].includes(result.data.code)) {
|
||||
// 检测到token过期
|
||||
if (isRefreshing == false) {
|
||||
isRefreshing = true;
|
||||
// 这里需要替换为实际的refresh token请求
|
||||
return axios.post('https://uc.ljsea.top/user/refresh_token', {
|
||||
refresh_token: localStorage.getItem("refresh_token")
|
||||
},{
|
||||
headers: {
|
||||
'Authorization': `Bearer ${localStorage.getItem("refresh_token")}`
|
||||
}
|
||||
}).then(res => {
|
||||
const token = res.data["data"]["access_token"];
|
||||
localStorage.setItem("token", token);
|
||||
//alert("token: " + token);
|
||||
|
||||
// 重试所有挂起的请求
|
||||
requests.forEach(cb => cb(token));
|
||||
requests = [];
|
||||
isRefreshing = false;
|
||||
|
||||
// 重试当前请求
|
||||
const config = result.config;
|
||||
config.headers.Authorization = `Bearer ${token}`;
|
||||
return request(config);
|
||||
}).catch(err => {
|
||||
// 刷新token失败,跳转登录
|
||||
ElMessage.error('登录已过期,请重新登录!');
|
||||
router.push("/login");
|
||||
return Promise.reject(err);
|
||||
});
|
||||
} else if (isRefreshing) {
|
||||
// 正在刷新token,将请求放入队列
|
||||
return new Promise(resolve => {
|
||||
requests.push(token => {
|
||||
//alert("new token: " + token);
|
||||
result.config.headers.Authorization = `Bearer ${token}`;
|
||||
result.config.headers.token = token;
|
||||
resolve(request(result.config));
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
if(result.data.code == 7) {
|
||||
alert("该用户已存在,请重新输入!");
|
||||
return null
|
||||
ElMessage.error('该用户已存在,请重新输入!');
|
||||
return null;
|
||||
}
|
||||
|
||||
if(result.data.code == 1) {
|
||||
alert("请求失败,请稍后重试!");
|
||||
ElMessage.error('请求失败,请稍后重试!');
|
||||
} else {
|
||||
return result.data
|
||||
return result.data;
|
||||
}
|
||||
},
|
||||
error => {
|
||||
alert("请求失败,请稍后重试!");
|
||||
return Promise.reject(error);
|
||||
}
|
||||
)
|
||||
request.interceptors.request.use(
|
||||
);
|
||||
|
||||
)
|
||||
export default request;
|
||||
|
|
@ -0,0 +1,94 @@
|
|||
import axios from "axios";
|
||||
import router from "@/router/index.js";
|
||||
import { ElMessage } from 'element-plus';
|
||||
//const baseURL = "https://gep.ljsea.top/";
|
||||
const baseURL = "https://uc.ljsea.top/";
|
||||
//const baseURL= "http://localhost:8083";
|
||||
//const baseURL="https://pm.ljsea.top";
|
||||
//const baseURL = "https://gep.ljsea.xyz/";
|
||||
|
||||
let isRefreshing = false;
|
||||
let requests = [];
|
||||
|
||||
const request = axios.create({
|
||||
baseURL: baseURL,
|
||||
});
|
||||
|
||||
// 请求拦截器 - 添加token
|
||||
request.interceptors.request.use(
|
||||
config => {
|
||||
const token = localStorage.getItem("token");
|
||||
if (token) {
|
||||
config.headers.Authorization = `Bearer ${token}`;
|
||||
config.headers.token = token;
|
||||
}
|
||||
return config;
|
||||
}
|
||||
);
|
||||
|
||||
// 响应拦截器
|
||||
request.interceptors.response.use(
|
||||
result => {
|
||||
if(result.status !== 200) {
|
||||
ElMessage.error('请求失败,请稍后重试!');
|
||||
router.push("/login");
|
||||
}
|
||||
|
||||
if(result.data.message === "NOT_LOGIN" || [2, 3, 4].includes(result.data.code)) {
|
||||
// 检测到token过期
|
||||
if (isRefreshing == false) {
|
||||
isRefreshing = true;
|
||||
// 这里需要替换为实际的refresh token请求
|
||||
return axios.post('https://uc.ljsea.top/user/refresh_token', {
|
||||
refresh_token: localStorage.getItem("refresh_token")
|
||||
},{
|
||||
headers: {
|
||||
'Authorization': `Bearer ${localStorage.getItem("refresh_token")}`
|
||||
}
|
||||
}).then(res => {
|
||||
const token = res.data["data"]["access_token"];
|
||||
localStorage.setItem("token", token);
|
||||
//alert("token: " + token);
|
||||
|
||||
// 重试所有挂起的请求
|
||||
requests.forEach(cb => cb(token));
|
||||
requests = [];
|
||||
isRefreshing = false;
|
||||
|
||||
// 重试当前请求
|
||||
const config = result.config;
|
||||
config.headers.Authorization = `Bearer ${token}`;
|
||||
return request(config);
|
||||
}).catch(err => {
|
||||
// 刷新token失败,跳转登录
|
||||
ElMessage.error('登录已过期,请重新登录!');
|
||||
router.push("/login");
|
||||
return Promise.reject(err);
|
||||
});
|
||||
} else if (isRefreshing) {
|
||||
// 正在刷新token,将请求放入队列
|
||||
return new Promise(resolve => {
|
||||
requests.push(token => {
|
||||
//alert("new token: " + token);
|
||||
result.config.headers.Authorization = `Bearer ${token}`;
|
||||
result.config.headers.token = token;
|
||||
resolve(request(result.config));
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
if(result.data.code == 7) {
|
||||
ElMessage.error('该用户已存在,请重新输入!');
|
||||
return null;
|
||||
}
|
||||
|
||||
if(result.data.code == 1) {
|
||||
ElMessage.error('请求失败,请稍后重试!');
|
||||
} else {
|
||||
return result.data;
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
export default request;
|
||||
|
|
@ -5,20 +5,28 @@ import { getCIDListService } from "@/api/cid.js";
|
|||
import { runCIDService } from "@/api/cid.js";
|
||||
import { addCIDService } from "@/api/cid.js";
|
||||
import { deleteCIDService } from "@/api/cid.js";
|
||||
import { updateCIDService } from "@/api/cid.js";
|
||||
import { updateCIDService,getCIDRuningListService } from "@/api/cid.js";
|
||||
import router from "@/router/index.js";
|
||||
import Menu from "@/views/Menu.vue";
|
||||
|
||||
import {ElMessage, ElLoading} from "element-plus";
|
||||
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
tableLoading: false,
|
||||
ip: "",
|
||||
tableData: [],
|
||||
timer: null, // 定时器
|
||||
tokenData: {
|
||||
server: localStorage.getItem("cid_server") || "gep.ljsea.xyz",
|
||||
token: localStorage.getItem("token"),
|
||||
ip: localStorage.getItem("ip"),
|
||||
userId: localStorage.getItem("userId"),
|
||||
username: localStorage.getItem("username"),
|
||||
},
|
||||
runningData: [],
|
||||
runningDialogVisible: false,
|
||||
addDialogVisible: false,
|
||||
updateDialogVisible: false,
|
||||
searchForm: {
|
||||
|
|
@ -27,14 +35,23 @@ export default {
|
|||
},
|
||||
addForm: {
|
||||
name: "",
|
||||
time: 0,
|
||||
url: "",
|
||||
script: "",
|
||||
token: localStorage.getItem("token"),
|
||||
},
|
||||
server_list: [
|
||||
{ label: "gep.ljsea.top", value: "gep.ljsea.top" },
|
||||
{ label: "gst.ljsea.top", value: "gst.ljsea.top" },
|
||||
{ label: "tx.ljsea.top", value: "tx.ljsea.top" },
|
||||
{ label: "js.ljsea.top", value: "js.ljsea.top" },
|
||||
{label: "as.ljsea.top", value: "as.ljsea.top"},
|
||||
],
|
||||
updateForm: {
|
||||
id:0,
|
||||
cidtoken:"",
|
||||
name: "",
|
||||
time:0,
|
||||
url: "",
|
||||
script: "",
|
||||
auth_id: -1,
|
||||
|
|
@ -43,23 +60,42 @@ export default {
|
|||
};
|
||||
},
|
||||
|
||||
watch: {
|
||||
// 监听 runningDialogVisible 的变化
|
||||
runningDialogVisible(newVal) {
|
||||
if (newVal) {
|
||||
// 当对话框显示时启动定时器,每秒执行一次
|
||||
this.timer = setInterval(() => {
|
||||
this.GetCIDRuningList();
|
||||
}, 1000);
|
||||
} else {
|
||||
// 当对话框隐藏时清除定时器
|
||||
if (this.timer) {
|
||||
clearInterval(this.timer);
|
||||
this.timer = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
// methods 是一些用来更改状态与触发更新的函数
|
||||
// 它们可以在模板中作为事件处理器绑定
|
||||
methods: {
|
||||
async getDeviceList() {
|
||||
async getCIDList() {
|
||||
this.tableLoading = true;
|
||||
let result = {};
|
||||
try {
|
||||
result = await getCIDListService(this.tokenData);
|
||||
let data = result.data;
|
||||
this.tableData = data;
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
} finally {
|
||||
this.tableLoading = false;
|
||||
}
|
||||
let data = result.data;
|
||||
|
||||
|
||||
this.tableData = data;
|
||||
},
|
||||
onSubmit() {
|
||||
getDeviceList({ token: token });
|
||||
getCIDList({ token: token });
|
||||
},
|
||||
handleSizeChange() {
|
||||
alert("每页记录数变化" + val);
|
||||
|
|
@ -70,6 +106,12 @@ export default {
|
|||
|
||||
//设置项目执行构建部署
|
||||
async runCID(index) {
|
||||
const loading = ElLoading.service({
|
||||
lock: true,
|
||||
text: '执行中',
|
||||
background: 'rgba(0, 0, 0, 0.7)',
|
||||
});
|
||||
try {
|
||||
var id = this.tableData[index].ID;
|
||||
var run_data = {
|
||||
id: id,
|
||||
|
|
@ -77,15 +119,17 @@ export default {
|
|||
userId: this.tokenData.userId,
|
||||
token: this.tokenData.token,
|
||||
};
|
||||
try {
|
||||
var d_re = await runCIDService(run_data);
|
||||
if (d_re.code == 0) {
|
||||
alert("操作成功");
|
||||
ElMessage.success("操作成功");
|
||||
} else {
|
||||
alert("操作失败");
|
||||
ElMessage.error("操作失败");
|
||||
}
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
} finally {
|
||||
loading.close();
|
||||
this.tableLoading = false;
|
||||
}
|
||||
},
|
||||
toRunCIDLog(index) {
|
||||
|
|
@ -94,23 +138,36 @@ export default {
|
|||
router.push("/cidlog");
|
||||
},
|
||||
async deleteCID(index) {
|
||||
//判断是否删除
|
||||
if (!confirm("是否删除")) {
|
||||
return;
|
||||
}
|
||||
|
||||
const loading = ElLoading.service({
|
||||
lock: true,
|
||||
text: '删除中',
|
||||
background: 'rgba(0, 0, 0, 0.7)',
|
||||
});
|
||||
try {
|
||||
var id = this.tableData[index].ID;
|
||||
var delete_data = {
|
||||
id: id,
|
||||
userId: this.tokenData.userId,
|
||||
token: this.tokenData.token,
|
||||
};
|
||||
try {
|
||||
var d_re = await deleteCIDService(delete_data);
|
||||
if (d_re.code == 0) {
|
||||
alert("删除成功");
|
||||
ElMessage.success("删除成功");
|
||||
//刷新页面
|
||||
this.getDeviceList();
|
||||
this.getCIDList();
|
||||
} else {
|
||||
alert("操作失败");
|
||||
ElMessage.error("操作失败");
|
||||
}
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
} finally {
|
||||
loading.close();
|
||||
this.tableLoading = false;
|
||||
}
|
||||
},
|
||||
async updateButtonCID(index) {
|
||||
|
|
@ -118,37 +175,74 @@ export default {
|
|||
this.updateForm.name = this.tableData[index].Name;
|
||||
this.updateForm.url = this.tableData[index].Url;
|
||||
this.updateForm.script = this.tableData[index].Script;
|
||||
this.updateForm.time = this.tableData[index].Time;
|
||||
this.updateForm.cidtoken = this.tableData[index].Token;
|
||||
this.updateForm.id = id;
|
||||
this.updateDialogVisible= true;
|
||||
},
|
||||
async addCID() {
|
||||
this.addDialogVisible = false;
|
||||
const loading = ElLoading.service({
|
||||
lock: true,
|
||||
text: '添加中',
|
||||
background: 'rgba(0, 0, 0, 0.7)',
|
||||
});
|
||||
let result = {};
|
||||
try {
|
||||
this.addForm.time = parseInt(this.addForm.time);
|
||||
result = await addCIDService(this.addForm);
|
||||
if (result.code == 0) {
|
||||
alert("添加成功");
|
||||
ElMessage.success("添加成功");
|
||||
this.getCIDList()
|
||||
} else {
|
||||
alert("添加失败");
|
||||
ElMessage.error("添加失败");
|
||||
}
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
} finally {
|
||||
loading.close();
|
||||
this.tableLoading = false;
|
||||
}
|
||||
},
|
||||
async updateCID() {
|
||||
this.updateDialogVisible = false;
|
||||
const loading = ElLoading.service({
|
||||
lock: true,
|
||||
text: '更新中',
|
||||
background: 'rgba(0, 0, 0, 0.7)',
|
||||
});
|
||||
let result = {};
|
||||
try {
|
||||
this.updateForm.time = parseInt(this.updateForm.time);
|
||||
result = await updateCIDService(this.updateForm);
|
||||
if (result.code == 0) {
|
||||
alert("修改成功");
|
||||
this.getDeviceList()
|
||||
ElMessage.success("修改成功");
|
||||
this.getCIDList()
|
||||
} else {
|
||||
alert("修改失败");
|
||||
ElMessage.error("修改失败");
|
||||
}
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
} finally {
|
||||
loading.close();
|
||||
this.tableLoading = false;
|
||||
}
|
||||
},
|
||||
async GetCIDRuningList(){
|
||||
let req = {
|
||||
token: this.tokenData.token,
|
||||
type: 0,
|
||||
}
|
||||
try{
|
||||
let result = await getCIDRuningListService(req);
|
||||
if(result.code == 0){
|
||||
this.runningData = result.data;
|
||||
this.runningDialogVisible = true;
|
||||
}else{
|
||||
ElMessage.error("获取失败");
|
||||
}
|
||||
}catch(e){
|
||||
console.log(e)
|
||||
}
|
||||
},
|
||||
async getIpClient() {
|
||||
|
|
@ -161,6 +255,10 @@ export default {
|
|||
console.error(error);
|
||||
}
|
||||
},
|
||||
handleServerChange(){
|
||||
localStorage.setItem("cid_server", this.tokenData.server);
|
||||
this.getCIDList()
|
||||
},
|
||||
handleMenuSelect(val) {
|
||||
router.push(val);
|
||||
},
|
||||
|
|
@ -187,38 +285,23 @@ export default {
|
|||
router.push("/login");
|
||||
}
|
||||
// console.log("mounted");
|
||||
await this.getIpClient();
|
||||
this.getDeviceList();
|
||||
this.getIpClient();
|
||||
this.getCIDList();
|
||||
},
|
||||
|
||||
// 组件销毁前清除定时器
|
||||
beforeUnmount() {
|
||||
if (this.timer) {
|
||||
clearInterval(this.timer);
|
||||
this.timer = null;
|
||||
}
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div>
|
||||
<el-button
|
||||
type="primary"
|
||||
size="mini"
|
||||
@click.prevent="handleMenuSelect('/videoList')"
|
||||
>视频列表</el-button
|
||||
>
|
||||
<el-button
|
||||
type="primary"
|
||||
size="mini"
|
||||
@click.prevent="handleMenuSelect('/device')"
|
||||
>设备管理</el-button
|
||||
>
|
||||
<el-button
|
||||
type="primary"
|
||||
size="mini"
|
||||
@click.prevent="handleMenuSelect('/User')"
|
||||
>用户</el-button
|
||||
>
|
||||
<el-button
|
||||
type="primary"
|
||||
size="mini"
|
||||
@click.prevent="handleMenuSelect('/cid')"
|
||||
>集成部署</el-button
|
||||
>
|
||||
<Menu></Menu>
|
||||
<el-container style="height: 700px; border: 1px solid #eee">
|
||||
<el-header style="font-size: 40px; background-color: rgb(238, 241, 246)"
|
||||
>集成部署项目</el-header
|
||||
|
|
@ -231,7 +314,7 @@ export default {
|
|||
<el-button
|
||||
class="el-button--danger"
|
||||
type="primary"
|
||||
@click="getDeviceList()"
|
||||
@click="getCIDList()"
|
||||
>查询</el-button
|
||||
>
|
||||
</el-form-item>
|
||||
|
|
@ -240,6 +323,23 @@ export default {
|
|||
>添加集成项目</el-button
|
||||
>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-select allow-create filterable v-model="tokenData.server" @change="handleServerChange">
|
||||
<el-option
|
||||
v-for="item in server_list"
|
||||
:key="item.value"
|
||||
:label="item.label"
|
||||
:value="item.value"
|
||||
></el-option>
|
||||
</el-select>
|
||||
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button type="primary" @click="GetCIDRuningList()"
|
||||
>正在运行</el-button
|
||||
>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item>
|
||||
<el-dialog
|
||||
v-model="addDialogVisible"
|
||||
|
|
@ -264,9 +364,20 @@ export default {
|
|||
<el-form-item label="仓库地址" prop="device_ip">
|
||||
<el-input v-model="addForm.url" style="width: 600px" autocomplete="on"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="定时执行时间" prop="time">
|
||||
<el-select v-model="addForm.time">
|
||||
<el-option label="30s" value="30"></el-option>
|
||||
<el-option label="1分钟" value="60"></el-option>
|
||||
<el-option label="1小时" value="3600"></el-option>
|
||||
<el-option label="1天" value="86400"></el-option>
|
||||
</el-select>
|
||||
自定义时间:
|
||||
<el-input type="textarea" v-model="addForm.time" autocomplete="on" style="width: 600px" />
|
||||
</el-form-item>
|
||||
<el-form-item label="脚本内容" prop="device_status">
|
||||
<el-input type="textarea" v-model="addForm.script" style="width: 600px" :autosize="{ minRows: 4, maxRows: 8 }" />
|
||||
</el-form-item>
|
||||
|
||||
</el-form>
|
||||
<!-- 底部区域 -->
|
||||
<template #footer>
|
||||
|
|
@ -311,7 +422,18 @@ export default {
|
|||
</el-form-item>
|
||||
<el-form-item label="外部回调Token" prop="device_status">
|
||||
<el-input v-model="updateForm.cidtoken" style="width: 600px" />
|
||||
回调地址:https://gep.ljsea.xyz/cid/callback?token={{updateForm.cidtoken}}&id={{updateForm.id}}
|
||||
回调地址:https://{{tokenData.server}}/cid/callback?token={{updateForm.cidtoken}}&id={{updateForm.id}}
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="定时执行时间" prop="time">
|
||||
<el-select v-model="updateForm.time">
|
||||
<el-option label="30s" value="30"></el-option>
|
||||
<el-option label="1分钟" value="60"></el-option>
|
||||
<el-option label="1小时" value="3600"></el-option>
|
||||
<el-option label="1天" value="86400"></el-option>
|
||||
</el-select>
|
||||
自定义时间:
|
||||
<el-input type="textarea" v-model="updateForm.time" autocomplete="on" style="width: 600px" />
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<!-- 底部区域 -->
|
||||
|
|
@ -326,11 +448,29 @@ export default {
|
|||
</span>
|
||||
</template>
|
||||
</el-dialog>
|
||||
<el-dialog
|
||||
v-model="runningDialogVisible"
|
||||
title="正在运行项目"
|
||||
width="50%"
|
||||
:before-close="handleClose"
|
||||
>
|
||||
<el-table
|
||||
:data="runningData"
|
||||
stripe
|
||||
width="90%"
|
||||
fit
|
||||
>
|
||||
<el-table-column prop="id" label="CID" width="150"></el-table-column>
|
||||
<el-table-column prop="cid" label="名称" width="150"></el-table-column>
|
||||
<el-table-column prop="start_time" label="开始时间" width="300">
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</el-dialog>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
|
||||
<!-- 表格 :row-style="this.tableRowClassName"-->
|
||||
<el-table :data="tableData" width="100%" border>
|
||||
<el-table :data="tableData" width="100%" v-loading="tableLoading">
|
||||
:row-style="this.tableRowClassName"
|
||||
<el-table-column prop="ID" label="id" width="80"></el-table-column>
|
||||
<el-table-column
|
||||
|
|
@ -346,11 +486,19 @@ export default {
|
|||
<el-table-column
|
||||
prop="Script"
|
||||
label="脚本消息"
|
||||
show-overflow-tooltip
|
||||
width="250"
|
||||
></el-table-column>
|
||||
<el-table-column
|
||||
prop="Token"
|
||||
label="回调Token"
|
||||
show-overflow-tooltip
|
||||
width="100"
|
||||
></el-table-column>
|
||||
<el-table-column
|
||||
prop="last_success"
|
||||
label="上次成功"
|
||||
show-overflow-tooltip
|
||||
width="100"
|
||||
></el-table-column>
|
||||
<el-table-column label="操作" width="350">
|
||||
|
|
|
|||
|
|
@ -7,12 +7,17 @@ import { addCIDService } from "@/api/cid.js";
|
|||
import { deleteCIDService } from "@/api/cid.js";
|
||||
import { updateCIDService } from "@/api/cid.js";
|
||||
import router from "@/router/index.js";
|
||||
import Menu from "@/views/Menu.vue";
|
||||
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
ip: "",
|
||||
tableData: [],
|
||||
currentPageData: [],
|
||||
loading: false,
|
||||
pageSize: 10,
|
||||
currentPage: 1,
|
||||
tokenData: {
|
||||
token: localStorage.getItem("token"),
|
||||
ip: localStorage.getItem("ip"),
|
||||
|
|
@ -34,26 +39,57 @@ export default {
|
|||
// methods 是一些用来更改状态与触发更新的函数
|
||||
// 它们可以在模板中作为事件处理器绑定
|
||||
methods: {
|
||||
roundNumber(number, decimals) {
|
||||
let num = 3.14159;
|
||||
let result = Math.round(number * 100) / 100;
|
||||
return result;
|
||||
},
|
||||
async getCIDLogList() {
|
||||
let result = {};
|
||||
this.loading = true;
|
||||
try {
|
||||
this.tokenData.id = parseInt(this.tokenData.id);
|
||||
result = await getCIDLogListService(this.tokenData);
|
||||
this.loading = false;
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
this.loading = false;
|
||||
}
|
||||
let data = result.data;
|
||||
|
||||
|
||||
for(var i=0;i<data.length;i++){
|
||||
data[i].RunTime = Math.round(data[i].RunTime * 100) / 100;
|
||||
}
|
||||
this.tableData = data;
|
||||
for(let i = 0;i<this.tableData.length;i++) {
|
||||
this.tableData[i].UpdatedAt = this.formattedTime(this.tableData[i].UpdatedAt);
|
||||
this.tableData[i].CreatedAt = this.formattedTime(this.tableData[i].CreatedAt)
|
||||
//console.log('this.ConfigFileList:',this.ConfigFileList);
|
||||
}
|
||||
this.handleCurrentChange(1);
|
||||
},
|
||||
formattedTime(isoTime) {
|
||||
const date = new Date(isoTime);
|
||||
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}`;
|
||||
},
|
||||
onSubmit() {
|
||||
getDeviceList({ token: token });
|
||||
},
|
||||
handleSizeChange() {
|
||||
alert("每页记录数变化" + val);
|
||||
handleSizeChange(val) {
|
||||
this.pageSize = val;
|
||||
},
|
||||
handleCurrentChange() {
|
||||
alert("页码发生变化" + val);
|
||||
handleCurrentChange(val) {
|
||||
this.currentPage = val;
|
||||
this.currentPageData = this.tableData.slice(
|
||||
(this.currentPage - 1) * this.pageSize,
|
||||
this.currentPage * this.pageSize
|
||||
);
|
||||
},
|
||||
|
||||
//设置项目执行构建部署
|
||||
|
|
@ -98,11 +134,18 @@ export default {
|
|||
},
|
||||
async updateButtonLogCID(index) {
|
||||
this.updateDialogVisible = true;
|
||||
var id = this.tableData[index].ID;
|
||||
this.updateForm.create_time = this.tableData[index].CreatedAt;
|
||||
this.updateForm.script = this.tableData[index].Script;
|
||||
this.updateForm.end = this.tableData[index].Log;
|
||||
this.updateForm.error = this.tableData[index].Error;
|
||||
// var id = this.tableData[index].ID;
|
||||
// this.updateForm.create_time = this.tableData[index].CreatedAt;
|
||||
// this.updateForm.script = this.tableData[index].Script;
|
||||
// this.updateForm.end = this.tableData[index].Log;
|
||||
// this.updateForm.error = this.tableData[index].Error;
|
||||
// this.updateForm.RunTime = this.tableData[index].RunTime;
|
||||
var id = this.currentPageData[index].ID;
|
||||
this.updateForm.create_time = this.currentPageData[index].CreatedAt;
|
||||
this.updateForm.script = this.currentPageData[index].Script;
|
||||
this.updateForm.end = this.currentPageData[index].Log;
|
||||
this.updateForm.error = this.currentPageData[index].Error;
|
||||
this.updateForm.RunTime = this.currentPageData[index].RunTime;
|
||||
},
|
||||
async getIpClient() {
|
||||
try {
|
||||
|
|
@ -140,7 +183,7 @@ export default {
|
|||
router.push("/login");
|
||||
}
|
||||
// console.log("mounted");
|
||||
await this.getIpClient();
|
||||
this.getIpClient();
|
||||
this.getCIDLogList();
|
||||
},
|
||||
};
|
||||
|
|
@ -148,30 +191,7 @@ export default {
|
|||
|
||||
<template>
|
||||
<div>
|
||||
<el-button
|
||||
type="primary"
|
||||
size="mini"
|
||||
@click.prevent="handleMenuSelect('/videoList')"
|
||||
>视频列表</el-button
|
||||
>
|
||||
<el-button
|
||||
type="primary"
|
||||
size="mini"
|
||||
@click.prevent="handleMenuSelect('/device')"
|
||||
>设备管理</el-button
|
||||
>
|
||||
<el-button
|
||||
type="primary"
|
||||
size="mini"
|
||||
@click.prevent="handleMenuSelect('/User')"
|
||||
>用户</el-button
|
||||
>
|
||||
<el-button
|
||||
type="primary"
|
||||
size="mini"
|
||||
@click.prevent="handleMenuSelect('/cid')"
|
||||
>集成部署</el-button
|
||||
>
|
||||
<Menu></Menu>
|
||||
<el-container style="height: 700px; border: 1px solid #eee">
|
||||
<el-header style="font-size: 40px; background-color: rgb(238, 241, 246)"
|
||||
>集成部署项目日志{{ tokenData.id }}</el-header
|
||||
|
|
@ -185,6 +205,7 @@ export default {
|
|||
class="el-button--danger"
|
||||
type="primary"
|
||||
@click="getCIDLogList()"
|
||||
:disabled="loading"
|
||||
>刷新</el-button
|
||||
>
|
||||
</el-form-item>
|
||||
|
|
@ -209,16 +230,29 @@ export default {
|
|||
autocomplete="on"
|
||||
style="width: 600px"
|
||||
></el-input>
|
||||
|
||||
</el-form-item>
|
||||
<el-col>
|
||||
<el-form-item label="执行时间" prop="run_time">
|
||||
<el-input
|
||||
v-model="updateForm.RunTime"
|
||||
autocomplete="on"
|
||||
style="width: 100px"
|
||||
></el-input>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-form-item label="脚本内容" prop="script">
|
||||
<el-input type="textarea" v-model="updateForm.script" style="width: 600px" :autosize="{ minRows: 4, maxRows: 8 }" />
|
||||
<el-input type="textarea" v-model="updateForm.script" style="width: 700px" :autosize="{ minRows: 4, maxRows: 8 }" />
|
||||
</el-form-item>
|
||||
<el-form-item label="执行结果" prop="end">
|
||||
<el-input type="textarea" v-model="updateForm.end" style="width: 600px" :autosize="{ minRows: 4, maxRows: 8 }" />
|
||||
<el-input type="textarea" v-model="updateForm.end" style="width: 700px" :autosize="{ minRows: 4, maxRows: 8 }" />
|
||||
</el-form-item>
|
||||
<el-col>
|
||||
<el-form-item label="错误内容" prop="error">
|
||||
<el-input type="textarea" v-model="updateForm.error" style="width: 600px" :autosize="{ minRows: 4, maxRows: 8 }" />
|
||||
<el-input type="textarea" v-model="updateForm.error" style="width: 700px" :autosize="{ minRows: 4, maxRows: 8 }" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
|
||||
</el-form>
|
||||
<!-- 底部区域 -->
|
||||
<template #footer>
|
||||
|
|
@ -233,29 +267,42 @@ export default {
|
|||
</el-form>
|
||||
|
||||
<!-- 表格 :row-style="this.tableRowClassName"-->
|
||||
<el-table :data="tableData" width="100%" border>
|
||||
<el-table
|
||||
:data="currentPageData"
|
||||
width="100%"
|
||||
v-loading="loading"
|
||||
element-loading-text="数据加载中..."
|
||||
>
|
||||
:row-style="this.tableRowClassName"
|
||||
<el-table-column prop="ID" label="id" width="80"></el-table-column>
|
||||
<el-table-column
|
||||
prop="CreatedAt"
|
||||
label="创建时间"
|
||||
width="100"
|
||||
show-overflow-tooltip
|
||||
width="200"
|
||||
></el-table-column>
|
||||
<el-table-column
|
||||
prop="Script"
|
||||
label="执行脚本"
|
||||
width="180"
|
||||
show-overflow-tooltip
|
||||
></el-table-column>
|
||||
<el-table-column
|
||||
prop="Log"
|
||||
label="运行日志"
|
||||
width="180"
|
||||
show-overflow-tooltip
|
||||
></el-table-column>
|
||||
<el-table-column
|
||||
prop="Error"
|
||||
label="错误信息"
|
||||
width="250"
|
||||
></el-table-column>
|
||||
<el-table-column
|
||||
prop="RunTime"
|
||||
label="运行时间(s)"
|
||||
width="80"
|
||||
></el-table-column>
|
||||
<el-table-column label="操作" width="350">
|
||||
<template #default="scope">
|
||||
<el-button
|
||||
|
|
@ -271,14 +318,15 @@ export default {
|
|||
<br />
|
||||
|
||||
<!-- 分页条 -->
|
||||
<!-- Pagination 分页 -->
|
||||
<!-- <el-pagination
|
||||
background
|
||||
layout="total,sizes, prev, pager, next, jumper"
|
||||
<el-pagination
|
||||
@size-change="handleSizeChange"
|
||||
@current-change="handleCurrentChange"
|
||||
:total="1000"
|
||||
></el-pagination> -->
|
||||
:current-page="currentPage"
|
||||
:page-sizes="[10, 20, 50, 100]"
|
||||
:page-size="pageSize"
|
||||
layout="total, sizes, prev, pager, next, jumper"
|
||||
:total="tableData.length">
|
||||
</el-pagination>
|
||||
</el-main>
|
||||
</el-container>
|
||||
</el-container>
|
||||
|
|
|
|||
|
|
@ -0,0 +1,902 @@
|
|||
<template>
|
||||
<el-dialog
|
||||
title="图片发送"
|
||||
v-model="sendImgDialogVisible"
|
||||
width="60%"
|
||||
height="60%"
|
||||
center
|
||||
>
|
||||
<!-- 图片输入 -->
|
||||
<input type="file" @change="handleFileUpload" />
|
||||
<el-button type="primary" size="default" @click="sendImageOrVideo"
|
||||
>发送</el-button
|
||||
>
|
||||
</el-dialog>
|
||||
|
||||
<el-container
|
||||
class="layout-container-demo"
|
||||
style="height: 700px; width: 1000px"
|
||||
>
|
||||
<el-aside width="200px">
|
||||
<el-input
|
||||
placeholder="请输入用户姓名"
|
||||
v-model="searchName"
|
||||
@input="filterUsers"
|
||||
></el-input>
|
||||
<el-scrollbar>
|
||||
<el-menu :default-openeds="['1', '3']">
|
||||
<el-sub-menu index="1">
|
||||
<template #title>
|
||||
<el-icon> <message /> </el-icon>联系人
|
||||
</template>
|
||||
<el-scrollbar height="300px">
|
||||
<el-menu-item-group v-for="user in filteredUsers" :key="user.id">
|
||||
<el-menu-item
|
||||
:index="String(user.id)"
|
||||
@click="handleGetMessage(user.id)"
|
||||
style="height: 40px"
|
||||
>
|
||||
<el-avatar style="float: left" :src="user.avatar"></el-avatar>
|
||||
{{ user.name }}
|
||||
|
||||
<span v-if="hasUnreadMsg[user.id]" class="unread-dot"></span>
|
||||
</el-menu-item>
|
||||
</el-menu-item-group>
|
||||
</el-scrollbar>
|
||||
</el-sub-menu>
|
||||
<el-sub-menu index="2">
|
||||
<template #title>
|
||||
<el-icon><icon-menu /></el-icon>
|
||||
群组
|
||||
</template>
|
||||
<el-scrollbar height="250px">
|
||||
<el-menu-item-group v-for="item in groupList" :key="item.ID">
|
||||
<!-- <template #title>Group 1</template> -->
|
||||
<el-menu-item
|
||||
:index="String(item.GroupName)"
|
||||
@click="handleGetGroupMessage(item.ID)"
|
||||
>{{ item.GroupName }}</el-menu-item
|
||||
>
|
||||
<span
|
||||
v-if="hasUnreadMsg[`g_${item.ID}`]"
|
||||
class="unread-dot"
|
||||
></span>
|
||||
<!-- <el-menu-item index="2-2">Option 2</el-menu-item> -->
|
||||
</el-menu-item-group>
|
||||
</el-scrollbar>
|
||||
</el-sub-menu>
|
||||
</el-menu>
|
||||
</el-scrollbar>
|
||||
</el-aside>
|
||||
|
||||
<el-container width="800px">
|
||||
<el-header style="text-align: right; font-size: 12px">
|
||||
<div class="toolbar">
|
||||
<el-button type="primary" size="mini" @click.prevent="getHistory()"
|
||||
>历史消息</el-button
|
||||
>
|
||||
<el-button
|
||||
type="primary"
|
||||
size="mini"
|
||||
@click.prevent="handleMenuSelect('/user')"
|
||||
>返回</el-button
|
||||
>
|
||||
<el-text class="mx-1" type="primary"
|
||||
>目前:{{ cur_user_name }}</el-text
|
||||
>
|
||||
|
||||
<div>
|
||||
<span style="margin-right: 10px; margin-left: 10px">{{
|
||||
username
|
||||
}}</span>
|
||||
<el-avatar size="default" fit="fit" :src="tokenData.avatar"></el-avatar>
|
||||
</div>
|
||||
</div>
|
||||
</el-header>
|
||||
|
||||
<el-main style="margin-top: 1px">
|
||||
<el-scrollbar
|
||||
class="chat-room"
|
||||
id="chat-room"
|
||||
ref="chatRoom"
|
||||
height="600px"
|
||||
style="margin-top: 1px"
|
||||
always
|
||||
>
|
||||
<div
|
||||
v-for="item in MsgList"
|
||||
:key="item.ID"
|
||||
style="margin-top: 10px; margin-bottom: 20px"
|
||||
>
|
||||
<!-- 左边 -->
|
||||
<div
|
||||
v-if="
|
||||
uid == item.ToUserID &&
|
||||
item.FromUserID == cur_user_id &&
|
||||
cur_group_id == 0
|
||||
"
|
||||
style="margin-left: 10px; margin-bottom: 8px"
|
||||
>
|
||||
<el-row class="row-bg" type="flex" align="middle">
|
||||
<!-- <el-avatar size="default" fit="fit">{{
|
||||
cur_user_name
|
||||
}}</el-avatar> -->
|
||||
<el-avatar size="default" :src="cur_user_avatar"></el-avatar>
|
||||
<span style="margin-left: 10px"
|
||||
>{{ cur_user_name }} : {{ formatTime(item.CreatedAt) }}</span
|
||||
>
|
||||
</el-row>
|
||||
|
||||
<el-row>
|
||||
<el-col :span="1000" :offset="1" class="msg">
|
||||
<!-- {{ item.Msg }} -->
|
||||
<div v-html="renderMarkdown(item.Msg)"></div>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</div>
|
||||
<div
|
||||
v-if="cur_group_id != 0 && uid != item.FromUserID"
|
||||
style="margin-left: 10px; margin-bottom: 8px"
|
||||
>
|
||||
<el-row class="row-bg" type="flex" align="middle">
|
||||
<el-avatar size="default" fit="fit">{{ item.name }}</el-avatar>
|
||||
<span style="margin-left: 10px"
|
||||
>{{ item.name }} : {{ formatTime(item.CreatedAt) }}</span
|
||||
>
|
||||
</el-row>
|
||||
|
||||
<el-row>
|
||||
<el-col
|
||||
:span="1000"
|
||||
:offset="1"
|
||||
class="msg"
|
||||
style="max-width: 50%"
|
||||
>
|
||||
<!-- {{ item.Msg }} -->
|
||||
<div
|
||||
v-html="renderMarkdown(item.Msg)"
|
||||
style="max-width: 50%"
|
||||
></div>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</div>
|
||||
<!-- 右边 -->
|
||||
<div
|
||||
v-if="uid == item.FromUserID && item.ToUserID == cur_user_id"
|
||||
style="margin-right: 10px; margin-bottom: 8px"
|
||||
>
|
||||
<el-row class="row-bg" type="flex" justify="end" align="middle">
|
||||
<span style="margin-right: 10px">
|
||||
{{ tokenData.username }} :
|
||||
{{ formatTime(item.CreatedAt) }}</span
|
||||
>
|
||||
<el-avatar size="default" :src="tokenData.avatar"></el-avatar>
|
||||
</el-row>
|
||||
|
||||
<el-row justify="end">
|
||||
<el-col
|
||||
:span="1000"
|
||||
class="msg2"
|
||||
style="margin-right: 20px; max-width: 50%"
|
||||
>
|
||||
<!-- {{ item.Msg }} -->
|
||||
<div
|
||||
v-html="renderMarkdown(item.Msg)"
|
||||
style="max-width: 50%"
|
||||
></div>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</div>
|
||||
</div>
|
||||
</el-scrollbar>
|
||||
</el-main>
|
||||
<div></div>
|
||||
<div>
|
||||
<el-row
|
||||
class="row-bg"
|
||||
type="flex"
|
||||
justify="space-around"
|
||||
align="middle"
|
||||
>
|
||||
<el-button
|
||||
type="primary"
|
||||
size="default"
|
||||
@click="SendImage"
|
||||
class="send-image-button-bg"
|
||||
>
|
||||
文件发送
|
||||
</el-button>
|
||||
<el-col :span="20">
|
||||
<el-input
|
||||
type="textarea"
|
||||
style="width: 100%"
|
||||
rows="1"
|
||||
autofocus
|
||||
@keyup.enter="handleSendBtnClick"
|
||||
placeholder="请输入消息按Enter发送"
|
||||
v-model="currentMsg"
|
||||
></el-input>
|
||||
</el-col>
|
||||
<el-col :span="2">
|
||||
<el-button
|
||||
class="sendBtn"
|
||||
@click="handleSendBtnClick"
|
||||
type="primary"
|
||||
size="default"
|
||||
>
|
||||
发送
|
||||
</el-button>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</div>
|
||||
</el-container>
|
||||
</el-container>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import axios from "axios";
|
||||
import { inject } from "vue";
|
||||
import { ref } from "vue";
|
||||
import { getFriendListService } from "@/api/chat.js";
|
||||
import { getMessageService } from "@/api/chat.js";
|
||||
import { sendMessageService } from "@/api/chat.js";
|
||||
import { UploadFileService } from "@/api/tool.js";
|
||||
import { GetFileInfoByMd5Service } from "@/api/tool.js";
|
||||
|
||||
import {
|
||||
ElAvatar,
|
||||
ElDropdown,
|
||||
ElDropdownItem,
|
||||
ElDropdownMenu,
|
||||
ElIcon,
|
||||
ElMenu,
|
||||
ElMenuItem,
|
||||
ElMenuItemGroup,
|
||||
ElScrollbar,
|
||||
ElRow,
|
||||
ElCol,
|
||||
ElButton,
|
||||
} from "element-plus";
|
||||
import { Menu as IconMenu, Message, Setting } from "@element-plus/icons-vue";
|
||||
import router from "@/router/index.js";
|
||||
import { ElMessage } from "element-plus";
|
||||
import MarkdownIt from "markdown-it";
|
||||
import CryptoJS from "crypto-js";
|
||||
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
ip: "",
|
||||
tableData: [],
|
||||
sendImgDialogVisible: false,
|
||||
file: null,
|
||||
file_md5: "",
|
||||
tokenData: {
|
||||
token: localStorage.getItem("token"),
|
||||
ip: localStorage.getItem("ip"),
|
||||
userId: localStorage.getItem("userId"),
|
||||
username: localStorage.getItem("username"),
|
||||
avatar:
|
||||
localStorage.getItem("avatar") === ""
|
||||
? "https://gep.ljsea.top/tool/file/9f29cc99-1054-4aff-ab37-e7c0016dd1b5.jpeg"
|
||||
: localStorage.getItem("avatar"),
|
||||
},
|
||||
username: localStorage.getItem("username"),
|
||||
userList: [],
|
||||
filteredUsers: [], // 过滤后的用户列表
|
||||
to_user_id: 0,
|
||||
cur_user_id: 0,
|
||||
cur_group_id: 0,
|
||||
msg_type: 1,
|
||||
searchName: "", // 搜索框内容
|
||||
history_cnt: 1,
|
||||
md: new MarkdownIt(), //md解析器
|
||||
|
||||
cur_user_name: "",
|
||||
cur_user_avatar: "",
|
||||
eventSource: null, // 事件源
|
||||
uid: localStorage.getItem("userId"),
|
||||
currentMsg: "",
|
||||
MsgList: [],
|
||||
groupList: [],
|
||||
hasUnreadMsg: {}, // 未读消息, key为用户id,value为true/false
|
||||
};
|
||||
},
|
||||
|
||||
// methods 是一些用来更改状态与触发更新的函数
|
||||
// 它们可以在模板中作为事件处理器绑定
|
||||
methods: {
|
||||
async handleSelectUser() {
|
||||
let result = {};
|
||||
try {
|
||||
result = await getFriendListService(this.tokenData);
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
}
|
||||
let data = result.data;
|
||||
this.userList = data.friends;
|
||||
for (let i = 0; i < data.friends.length; i++) {
|
||||
this.userList[i].avatar = data.friends[i].avatar ===""?"https://gep.ljsea.top/tool/file/9f29cc99-1054-4aff-ab37-e7c0016dd1b5.jpeg" : data.friends[i].avatar;
|
||||
this.hasUnreadMsg[data.friends[i].id] = false;
|
||||
}
|
||||
console.log("avatar: " + this.userList[0].avatar);
|
||||
for (let i = 0; i < data.groups.length; i++) {
|
||||
this.hasUnreadMsg["g_" + data.groups[i].ID] = false;
|
||||
}
|
||||
this.groupList = data.groups;
|
||||
},
|
||||
filterUsers() {
|
||||
this.filteredUsers = this.userList.filter((user) => {
|
||||
return user.name.toLowerCase().includes(this.searchName.toLowerCase());
|
||||
});
|
||||
},
|
||||
getHistory() {
|
||||
this.history_cnt++;
|
||||
this.handleGetMessage(this.cur_user_id);
|
||||
},
|
||||
async handleGetGroupMessage(id) {
|
||||
this.cur_group_id = id;
|
||||
this.cur_user_id = 0;
|
||||
this.to_user_id = 0;
|
||||
this.msg_type = 2;
|
||||
this.hasUnreadMsg["g_" + id] = false;
|
||||
let result = {};
|
||||
try {
|
||||
let req = {
|
||||
token: localStorage.getItem("token"),
|
||||
ip: localStorage.getItem("ip"),
|
||||
userId: localStorage.getItem("userId"),
|
||||
username: localStorage.getItem("username"),
|
||||
group_id: id,
|
||||
index: this.history_cnt,
|
||||
type: 2,
|
||||
};
|
||||
result = await getMessageService(req);
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
}
|
||||
let data = result.data;
|
||||
if (data === undefined || data === null) {
|
||||
ElMessage({
|
||||
message: "无消息!",
|
||||
type: "error",
|
||||
});
|
||||
this.MsgList = [];
|
||||
return;
|
||||
}
|
||||
data.sort((a, b) => {
|
||||
const dateA = new Date(a.CreatedAt);
|
||||
const dateB = new Date(b.CreatedAt);
|
||||
|
||||
// 返回时间差,用于排序
|
||||
return dateA - dateB;
|
||||
});
|
||||
this.MsgList = data;
|
||||
if (this.history_cnt <= 2) {
|
||||
this.scrollToBottom();
|
||||
}
|
||||
},
|
||||
async handleGetMessage(id) {
|
||||
let result = {};
|
||||
if (this.to_user_id != id) {
|
||||
this.history_cnt = 2;
|
||||
}
|
||||
this.to_user_id = id;
|
||||
this.cur_user_id = id;
|
||||
this.cur_group_id = 0;
|
||||
this.msg_type = 1;
|
||||
console.log("uid:", this.uid, "\tcur_user_id:", this.cur_user_id);
|
||||
for (let i = 0; i < this.userList.length; i++) {
|
||||
if (this.userList[i].id === id) {
|
||||
this.cur_user_name = this.userList[i].name;
|
||||
this.cur_user_avatar =
|
||||
this.userList[i].avatar === ""
|
||||
? "https://gep.ljsea.top/tool/file/9f29cc99-1054-4aff-ab37-e7c0016dd1b5.jpeg"
|
||||
: this.userList[i].avatar;
|
||||
break;
|
||||
}
|
||||
}
|
||||
this.hasUnreadMsg[id] = false;
|
||||
try {
|
||||
let req = {
|
||||
token: localStorage.getItem("token"),
|
||||
ip: localStorage.getItem("ip"),
|
||||
userId: localStorage.getItem("userId"),
|
||||
username: localStorage.getItem("username"),
|
||||
from_user_id: id,
|
||||
to_user_id: localStorage.getItem("userId"),
|
||||
index: this.history_cnt,
|
||||
type: this.msg_type,
|
||||
};
|
||||
result = await getMessageService(req);
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
}
|
||||
let data = result.data;
|
||||
if (data === undefined) {
|
||||
ElMessage({
|
||||
message: "消息获取失败!",
|
||||
type: "error",
|
||||
});
|
||||
return;
|
||||
}
|
||||
//data sort by created time
|
||||
// for (let i = 0; i < data.length; i++) {
|
||||
// for (let j = i + 1; j < data.length; j++) {
|
||||
// if (data[i].CreatedAt > data[j].CreatedAt) {
|
||||
// let temp = data[i];
|
||||
// data[i] = data[j];
|
||||
// data[j] = temp;
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
data.sort((a, b) => {
|
||||
const dateA = new Date(a.CreatedAt);
|
||||
const dateB = new Date(b.CreatedAt);
|
||||
|
||||
// 返回时间差,用于排序
|
||||
return dateA - dateB;
|
||||
});
|
||||
this.MsgList = data;
|
||||
if (this.history_cnt <= 2) {
|
||||
this.scrollToBottom();
|
||||
}
|
||||
},
|
||||
formatTime(time) {
|
||||
let date = new Date(time);
|
||||
// 提取年、月、日、时、分、秒
|
||||
const year = date.getFullYear();
|
||||
const month = ("0" + (date.getMonth() + 1)).slice(-2); // 月份是从0开始的,所以要加1
|
||||
const day = ("0" + date.getDate()).slice(-2);
|
||||
const hour = ("0" + date.getHours()).slice(-2);
|
||||
const minute = ("0" + date.getMinutes()).slice(-2);
|
||||
const second = ("0" + date.getSeconds()).slice(-2);
|
||||
|
||||
// 重新组合并返回格式化的日期时间字符串
|
||||
return `${year}-${month}-${day} ${hour}:${minute}:${second}`;
|
||||
},
|
||||
renderMarkdown(markdown) {
|
||||
// 使用 MarkdownIt 解析 Markdown 字符串并返回 HTML
|
||||
return this.md.render(markdown);
|
||||
},
|
||||
SendImage() {
|
||||
this.sendImgDialogVisible = true;
|
||||
},
|
||||
|
||||
connectWebSocket() {
|
||||
// 连接WebSocket
|
||||
let _this = this;
|
||||
if (typeof WebSocket == "undefined") {
|
||||
console.log("浏览器不支持WebSocket");
|
||||
} else {
|
||||
console.log("浏览器支持WebSocket");
|
||||
let socketUrl =
|
||||
"wss://tx.ljsea.top/im/ws_v2?to_user_id=" +
|
||||
this.to_user_id +
|
||||
"&token=" +
|
||||
this.tokenData.token;
|
||||
|
||||
// console.log("socketUrl:", socketUrl);
|
||||
if (this.socket != null) {
|
||||
this.socket.close();
|
||||
this.socket = null;
|
||||
}
|
||||
// 开启一个websocket服务
|
||||
this.socket = new WebSocket(socketUrl);
|
||||
//打开事件
|
||||
this.socket.onopen = function () {
|
||||
this.loading = false;
|
||||
//alert("连接成功");
|
||||
ElMessage({
|
||||
message: "连接成功",
|
||||
type: "success",
|
||||
});
|
||||
};
|
||||
this.socket.onerror = (error) => {
|
||||
console.error("WebSocket Error:", error);
|
||||
};
|
||||
//关闭事件
|
||||
this.socket.onclose = function () {
|
||||
//alert("连接已关闭!");
|
||||
ElMessage({
|
||||
message: "连接已关闭",
|
||||
type: "error",
|
||||
});
|
||||
};
|
||||
// 浏览器端收消息,获得从服务端发送过来的文本消息
|
||||
this.socket.onmessage = async function (msg) {
|
||||
//console.log("收到数据====" + msg.data);
|
||||
let data = JSON.parse(msg.data); // 对收到的json数据进行解析, 类似这样的:
|
||||
// console.log("收到数据====" + data);
|
||||
// 如果服务器端发送过来的json数据
|
||||
console.log("data.type:", data.type);
|
||||
if (data.type == "msg") {
|
||||
// 如果是消息类型,解密消息内容
|
||||
// console.log("收到数据====" + JSON.stringify(msg.data));
|
||||
console.log("msg_:", data.data);
|
||||
console.log("hasUnreadMsg:", _this.hasUnreadMsg);
|
||||
let msg_data = JSON.parse(data.data);
|
||||
_this.MsgList.push(msg_data);
|
||||
if (msg_data.GroupID === 0) {
|
||||
//如果msg_data.GroupID === 0,则为用户消息
|
||||
if (msg_data.FromUserID !== _this.cur_user_id) {
|
||||
//如果不是是当前用户发送的消息,则设置为未读
|
||||
_this.hasUnreadMsg[msg_data.FromUserID] = true;
|
||||
//将当前用户移动到第一位
|
||||
for (let i = 0; i < _this.userList.length; i++) {
|
||||
if (_this.userList[i].id === msg_data.FromUserID) {
|
||||
let temp = _this.userList[i];
|
||||
_this.userList.splice(i, 1); //删除当前用户
|
||||
_this.userList.unshift(temp); //将当前用户移动到第一位
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (msg_data.GroupID !== _this.cur_group_id) {
|
||||
//如果不是是当前用户发送的消息,则设置为未读
|
||||
_this.hasUnreadMsg["g_" + msg_data.GroupID] = true;
|
||||
//将当前用户移动到第一位
|
||||
for (let i = 0; i < _this.groupList.length; i++) {
|
||||
if (_this.groupList[i].ID === msg_data.GroupID) {
|
||||
let temp = _this.groupList[i];
|
||||
_this.groupList.splice(i, 1); //删除当前用户
|
||||
_this.groupList.unshift(temp); //将当前用户移动到第一位
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
_this.scrollToBottom();
|
||||
//console.log("msglist:", _this.MsgList);
|
||||
// 构建消息内容
|
||||
} else if (data.type == "check") {
|
||||
//alert("对方已下线");
|
||||
//console.log(data.type);
|
||||
}
|
||||
};
|
||||
}
|
||||
},
|
||||
async connectSSE() {
|
||||
if (!!window.EventSource) {
|
||||
this.eventSource = new EventSource(
|
||||
"https://gep.ljsea.xyz/im/sse_msg?token=" + this.tokenData.token
|
||||
);
|
||||
let this_ = this;
|
||||
this.eventSource.onopen = function (event) {
|
||||
console.log("连接已建立!");
|
||||
};
|
||||
this.eventSource.onmessage = function (event) {
|
||||
console.log(event.data);
|
||||
let msg = JSON.parse(event.data);
|
||||
if (msg.type !== "check") {
|
||||
alert(msg);
|
||||
this_.MsgList.push(msg);
|
||||
}
|
||||
};
|
||||
this.eventSource.onerror = (error) => {
|
||||
//重新连接
|
||||
this.connectSSE();
|
||||
if (this.eventSource.readyState === EventSource.CLOSED) {
|
||||
//console.log('Connection was closed by the server.');
|
||||
ElMessage({
|
||||
message: "连接已关闭!:" + error,
|
||||
type: "error",
|
||||
});
|
||||
|
||||
// Optionally, try to reconnect
|
||||
} else {
|
||||
//console.error('EventSource failed:', error);
|
||||
ElMessage({
|
||||
message: "连接失败!服务器无法实时推送消息!",
|
||||
type: "error",
|
||||
});
|
||||
// Handle error
|
||||
}
|
||||
};
|
||||
} else {
|
||||
ElMessage({
|
||||
message: "您的浏览器不支持SSE!",
|
||||
type: "error",
|
||||
});
|
||||
}
|
||||
},
|
||||
scrollToBottom() {
|
||||
this.$nextTick(() => {
|
||||
const scrollbar = this.$refs.chatRoom.$el.querySelector(
|
||||
".el-scrollbar__wrap"
|
||||
);
|
||||
if (scrollbar) {
|
||||
scrollbar.scrollTop = scrollbar.scrollHeight;
|
||||
}
|
||||
});
|
||||
},
|
||||
async handleSendBtnClick() {
|
||||
if (this.currentMsg == "" || this.currentMsg === null) {
|
||||
ElMessage.error("消息不能为空!");
|
||||
return;
|
||||
}
|
||||
let result = {};
|
||||
try {
|
||||
let req = {
|
||||
token: localStorage.getItem("token"),
|
||||
ip: localStorage.getItem("ip"),
|
||||
userId: localStorage.getItem("userId"),
|
||||
username: localStorage.getItem("username"),
|
||||
from_user_id: localStorage.getItem("userId"),
|
||||
to_user_id: this.to_user_id,
|
||||
group_id: this.cur_group_id,
|
||||
msg: this.currentMsg,
|
||||
type: this.msg_type,
|
||||
};
|
||||
result = await sendMessageService(req);
|
||||
if (result.code !== 0) {
|
||||
ElMessage({
|
||||
message: "消息发送失败!",
|
||||
type: "error",
|
||||
});
|
||||
}
|
||||
let msg = {
|
||||
ID: result.Data,
|
||||
FromUserID: localStorage.getItem("userId"),
|
||||
ToUserID: this.to_user_id,
|
||||
GroupID: this.cur_group_id,
|
||||
Msg: this.currentMsg,
|
||||
CreatedAt: new Date(),
|
||||
};
|
||||
this.MsgList.push(msg);
|
||||
this.scrollToBottom();
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
}
|
||||
this.currentMsg = "";
|
||||
},
|
||||
async getIpClient() {
|
||||
try {
|
||||
const response = await axios.get("https://ipinfo.io/json");
|
||||
this.ip = response.data.ip;
|
||||
localStorage.setItem("ip", this.ip);
|
||||
//console.log(response);
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
}
|
||||
},
|
||||
handleFileSelect() {
|
||||
let mdt_ = "";
|
||||
if (this.file) {
|
||||
try {
|
||||
const reader = new FileReader();
|
||||
reader.onloadend = function (e) {
|
||||
if (e.target.readyState === FileReader.DONE) {
|
||||
const arrayBuffer = e.target.result;
|
||||
const spark = new SparkMD5.ArrayBuffer();
|
||||
spark.append(arrayBuffer);
|
||||
md5Value.value = spark.end();
|
||||
}
|
||||
};
|
||||
reader.readAsArrayBuffer(this.file);
|
||||
} catch (error) {
|
||||
console.error("计算MD5值出错:", error);
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
handleMenuSelect(val) {
|
||||
router.push(val);
|
||||
//关闭websocket
|
||||
if (this.socket != null) {
|
||||
this.socket.close();
|
||||
}
|
||||
},
|
||||
handleFileUpload(e) {
|
||||
this.file = e.target.files[0];
|
||||
console.log("file has been selected:", this.file);
|
||||
},
|
||||
readFileAndCalculateMD5() {
|
||||
return new Promise((resolve, reject) => {
|
||||
const reader = new FileReader();
|
||||
reader.onload = (event) => {
|
||||
const wordArray = CryptoJS.lib.WordArray.create(event.target.result);
|
||||
const md5Hash = CryptoJS.MD5(wordArray);
|
||||
const md5Str = md5Hash.toString(CryptoJS.enc.Hex);
|
||||
//console.log("onload: " + md5Str);
|
||||
this.file_md5 = md5Str;
|
||||
resolve(md5Str);
|
||||
};
|
||||
reader.onerror = (error) => {
|
||||
reject(error);
|
||||
};
|
||||
reader.readAsArrayBuffer(this.file);
|
||||
});
|
||||
},
|
||||
async sendImageOrVideo() {
|
||||
if (this.file == null) {
|
||||
alert("请先选择要上传的文件");
|
||||
return;
|
||||
}
|
||||
//查看文件是否是图片或视频
|
||||
|
||||
try {
|
||||
let result = {};
|
||||
this.file_md5 = await this.readFileAndCalculateMD5(this.file);
|
||||
//console.log("md5:",this.file_md5);
|
||||
let md5_result = await GetFileInfoByMd5Service({
|
||||
md5: this.file_md5,
|
||||
token: this.tokenData.token,
|
||||
type: 1,
|
||||
});
|
||||
if (md5_result.code === 0) {
|
||||
result = md5_result;
|
||||
} else {
|
||||
let formData = new FormData();
|
||||
formData.append("file", this.file);
|
||||
//console.log("add file: " + this.file);
|
||||
formData.append("upload_type", "1");
|
||||
formData.append("md5", this.file_md5);
|
||||
formData.append("auth_type", "public");
|
||||
//console.log("formData:",formData);
|
||||
|
||||
result = await UploadFileService(formData, this.tokenData.token);
|
||||
if (result.code !== 0) {
|
||||
ElMessage.error("上传文件失败,请稍后再试");
|
||||
return;
|
||||
}
|
||||
}
|
||||
let resp_data = result.data;
|
||||
|
||||
//console.log("resp:",resp_data);
|
||||
let url = "https://gep.ljsea.top/tool/file/" + resp_data.FileStoreName;
|
||||
let msg_ = "";
|
||||
//markdown 图片格式
|
||||
let fileType = this.file.name.split(".")[1];
|
||||
if (!["jpg", "jpeg", "png", "gif", "mp4"].includes(fileType)) {
|
||||
//alert('请选择正确的图片或视频格式');
|
||||
msg_ = `文件:[${resp_data.FileName}](${url})`;
|
||||
} else {
|
||||
msg_ = ``;
|
||||
}
|
||||
|
||||
let req = {
|
||||
token: localStorage.getItem("token"),
|
||||
ip: localStorage.getItem("ip"),
|
||||
userId: localStorage.getItem("userId"),
|
||||
username: localStorage.getItem("username"),
|
||||
from_user_id: localStorage.getItem("userId"),
|
||||
to_user_id: this.to_user_id,
|
||||
group_id: this.cur_group_id,
|
||||
msg: msg_,
|
||||
type: this.msg_type,
|
||||
};
|
||||
result = await sendMessageService(req);
|
||||
if (result.code !== 0) {
|
||||
ElMessage({
|
||||
message: "消息发送失败!",
|
||||
type: "error",
|
||||
});
|
||||
}
|
||||
let msg = {
|
||||
ID: result.data.id,
|
||||
FromUserID: localStorage.getItem("userId"),
|
||||
ToUserID: this.to_user_id,
|
||||
GroupID: this.cur_group_id,
|
||||
Msg: msg_,
|
||||
CreatedAt: new Date(),
|
||||
};
|
||||
console.log("msg:", msg);
|
||||
this.MsgList.push(msg);
|
||||
this.scrollToBottom();
|
||||
this.sendImgDialogVisible = false;
|
||||
} catch (error) {
|
||||
ElMessage.error("上传文件时出现网络错误,请稍后再试");
|
||||
console.error(error);
|
||||
}
|
||||
},
|
||||
toVideoList() {
|
||||
router.push("/videoList");
|
||||
},
|
||||
// 修改条纹颜色
|
||||
tableRowClassName({ row, rowIndex }) {
|
||||
if (row.human === 1) {
|
||||
return {
|
||||
background: "#488aff",
|
||||
};
|
||||
} else {
|
||||
return "";
|
||||
}
|
||||
},
|
||||
},
|
||||
|
||||
// 生命周期钩子会在组件生命周期的各个不同阶段被调用
|
||||
// 例如这个函数就会在组件挂载完成后被调用
|
||||
async mounted() {
|
||||
let now = new Date();
|
||||
if (localStorage.getItem("token") === null) {
|
||||
router.push("/login");
|
||||
}
|
||||
// console.log("mounted");
|
||||
await this.getIpClient();
|
||||
await this.handleSelectUser();
|
||||
this.filteredUsers = this.userList;
|
||||
//await this.connectSSE();
|
||||
this.connectWebSocket();
|
||||
this.handleGetMessage(this.userList[0].id);
|
||||
},
|
||||
onUnmounted() {
|
||||
if (this.eventSource) {
|
||||
this.eventSource.close();
|
||||
}
|
||||
console.log("unmounted chat");
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.layout-container-demo .el-header {
|
||||
position: relative;
|
||||
/* background-color: var(--el-color-primary-light-7); */
|
||||
color: var(--el-text-color-primary);
|
||||
}
|
||||
|
||||
.layout-container-demo .el-aside {
|
||||
color: var(--el-text-color-primary);
|
||||
/* background: var(--el-color-primary-light-8); */
|
||||
}
|
||||
|
||||
.layout-container-demo .el-menu {
|
||||
border-right: none;
|
||||
}
|
||||
|
||||
.layout-container-demo .el-main {
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.layout-container-demo .toolbar {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
height: 100%;
|
||||
right: 5px;
|
||||
}
|
||||
|
||||
.msg {
|
||||
background-color: #73d1f3;
|
||||
/* box-shadow: rgba(18, 23, 45, 0.6) 0px 8px 24px; */
|
||||
border-radius: 4px;
|
||||
padding: 10px;
|
||||
font-size: 18px;
|
||||
line-height: 16px;
|
||||
/* width: auto; */
|
||||
/* max-width: 330px; */
|
||||
margin-top: 20px;
|
||||
color: white;
|
||||
}
|
||||
|
||||
.msg2 {
|
||||
background-color: #12b7f5;
|
||||
/* box-shadow: rgba(18, 23, 45, 0.6) 0px 8px 24px; */
|
||||
border-radius: 4px;
|
||||
padding: 10px;
|
||||
font-size: 18px;
|
||||
line-height: 16px;
|
||||
/* width: auto; */
|
||||
/* max-width: 330px; */
|
||||
margin-top: 20px;
|
||||
color: white;
|
||||
}
|
||||
.unread-dot {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: 0;
|
||||
width: 8px;
|
||||
height: 8px;
|
||||
background-color: red;
|
||||
border-radius: 50%;
|
||||
transform: translate(50%, -50%);
|
||||
}
|
||||
|
||||
.send-image-button-bg {
|
||||
background-image: url(../assets/img.jpg);
|
||||
background-size: cover;
|
||||
background-repeat: no-repeat;
|
||||
}
|
||||
</style>
|
||||
|
|
@ -7,8 +7,14 @@ import { addDeviceService } from "@/api/device.js";
|
|||
import { deleteDeviceService } from "@/api/device.js";
|
||||
import { updateDeviceService } from "@/api/device.js";
|
||||
import router from "@/router/index.js";
|
||||
import { ElMessage } from 'element-plus';
|
||||
import Menu from "@/views/Menu.vue";
|
||||
import VideoStream from "@/views/DeviceRealVPV2.vue";
|
||||
|
||||
export default {
|
||||
components: {
|
||||
VideoStream,
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
ip: "",
|
||||
|
|
@ -21,6 +27,8 @@ export default {
|
|||
},
|
||||
addDialogVisible: false,
|
||||
updateDialogVisible: false,
|
||||
deviceStreamDialogVisible: false,
|
||||
playing_device: "",
|
||||
searchForm: {
|
||||
hour: 0,
|
||||
entrydate: [],
|
||||
|
|
@ -93,9 +101,11 @@ export default {
|
|||
try {
|
||||
var d_re = await restartDeviceService(restart_data);
|
||||
if (d_re.code == 0) {
|
||||
alert("重启成功");
|
||||
//alert("重启成功");
|
||||
ElMessage.success('重启成功');
|
||||
} else {
|
||||
alert("操作失败");
|
||||
ElMessage.fail('操作失败');
|
||||
}
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
|
|
@ -104,9 +114,17 @@ export default {
|
|||
playRealVp(index) {
|
||||
var id = this.tableData[index].ID;
|
||||
localStorage.setItem("realvp_device_id", id);
|
||||
router.push("/deviceRealVP");
|
||||
// router.push("/deviceRealVP");
|
||||
this.playing_device = id + " " + this.tableData[index].DeviceName;
|
||||
this.deviceStreamDialogVisible = true;
|
||||
},
|
||||
async deleteDevice(index) {
|
||||
// 删除前确认
|
||||
if (!confirm("确定删除吗?")) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
var id = this.tableData[index].ID;
|
||||
var delete_data = {
|
||||
id: id,
|
||||
|
|
@ -116,11 +134,13 @@ export default {
|
|||
try {
|
||||
var d_re = await deleteDeviceService(delete_data);
|
||||
if (d_re.code == 0) {
|
||||
alert("删除成功");
|
||||
//alert("删除成功");
|
||||
ElMessage.success('删除成功');
|
||||
//刷新页面
|
||||
this.getDeviceList();
|
||||
} else {
|
||||
alert("操作失败");
|
||||
//alert("操作失败");
|
||||
ElMessage.fail("操作失败");
|
||||
}
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
|
|
@ -144,9 +164,11 @@ export default {
|
|||
try {
|
||||
result = await addDeviceService(this.addForm);
|
||||
if (result.code == 0) {
|
||||
alert("添加成功");
|
||||
ElMessage.success("添加成功");
|
||||
this.getDeviceList()
|
||||
} else {
|
||||
alert("添加失败");
|
||||
//alert("添加失败");
|
||||
ElMessage.error("添加失败")
|
||||
}
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
|
|
@ -158,7 +180,8 @@ export default {
|
|||
try {
|
||||
result = await updateDeviceService(this.updateForm);
|
||||
if (result.code == 0) {
|
||||
alert("修改成功");
|
||||
//alert("修改成功");
|
||||
ElMessage.success("修改成功");
|
||||
this.getDeviceList()
|
||||
} else {
|
||||
alert("修改失败");
|
||||
|
|
@ -178,7 +201,8 @@ export default {
|
|||
try {
|
||||
var d_re = await restartDeviceService(restart_data);
|
||||
if (d_re.code == 0) {
|
||||
alert("重启成功");
|
||||
//alert("重启成功");
|
||||
ElMessage.success("重启成功");
|
||||
} else {
|
||||
alert("操作失败");
|
||||
}
|
||||
|
|
@ -222,7 +246,7 @@ export default {
|
|||
router.push("/login");
|
||||
}
|
||||
// console.log("mounted");
|
||||
await this.getIpClient();
|
||||
//this.getIpClient();
|
||||
this.getDeviceList();
|
||||
},
|
||||
};
|
||||
|
|
@ -230,30 +254,7 @@ export default {
|
|||
|
||||
<template>
|
||||
<div>
|
||||
<el-button
|
||||
type="primary"
|
||||
size="mini"
|
||||
@click.prevent="handleMenuSelect('/videoList')"
|
||||
>视频列表</el-button
|
||||
>
|
||||
<el-button
|
||||
type="primary"
|
||||
size="mini"
|
||||
@click.prevent="handleMenuSelect('/device')"
|
||||
>设备管理</el-button
|
||||
>
|
||||
<el-button
|
||||
type="primary"
|
||||
size="mini"
|
||||
@click.prevent="handleMenuSelect('/User')"
|
||||
>用户</el-button
|
||||
>
|
||||
<el-button
|
||||
type="primary"
|
||||
size="mini"
|
||||
@click.prevent="handleMenuSelect('/cid')"
|
||||
>集成部署</el-button
|
||||
>
|
||||
<Menu></Menu>
|
||||
<el-container style="height: 700px; border: 1px solid #eee">
|
||||
<el-header style="font-size: 40px; background-color: rgb(238, 241, 246)"
|
||||
>监控设备列表</el-header
|
||||
|
|
@ -332,6 +333,20 @@ export default {
|
|||
</template>
|
||||
</el-dialog>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-dialog
|
||||
title="实时播放"
|
||||
v-model="deviceStreamDialogVisible"
|
||||
width="60%"
|
||||
height="60%"
|
||||
center
|
||||
>
|
||||
<div>
|
||||
视频播放({{playing_device }}):
|
||||
<VideoStream v-if="deviceStreamDialogVisible"></VideoStream>
|
||||
</div>
|
||||
</el-dialog>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item>
|
||||
<el-dialog
|
||||
|
|
@ -410,7 +425,15 @@ export default {
|
|||
prop="DeviceStatus"
|
||||
label="设备状态"
|
||||
width="80"
|
||||
></el-table-column>
|
||||
>
|
||||
<template #default="scope">
|
||||
<el-tag
|
||||
:type="scope.row.DeviceStatus === '在线' ? 'success' : 'danger'"
|
||||
>{{ scope.row.DeviceStatus === "在线" ? '在线' : '离线' }}</el-tag
|
||||
>
|
||||
</template>
|
||||
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
prop="DeviceType"
|
||||
label="设备类型"
|
||||
|
|
|
|||
|
|
@ -1,18 +1,19 @@
|
|||
<template>
|
||||
<el-button
|
||||
<!-- <el-button
|
||||
type="primary"
|
||||
size="mini"
|
||||
@click.prevent="handleMenuSelect('/device')"
|
||||
>设备</el-button
|
||||
>
|
||||
> -->
|
||||
<div>
|
||||
<!-- 使用:src绑定base64图片 -->
|
||||
<img :src="base64Image" alt="Base64 Image" />
|
||||
<img :src="base64Image" alt="Base64 Image" width="100%" height ="100%"/>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
import { ref, onMounted, inject, onUnmounted } from "vue";
|
||||
import router from "@/router/index.js";
|
||||
import { ElMessage } from 'element-plus';
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
|
|
@ -35,6 +36,7 @@ export default {
|
|||
},
|
||||
methods: {
|
||||
handleMenuSelect(val) {
|
||||
this.socket.close();
|
||||
router.push(val);
|
||||
},
|
||||
connectWebSocket() {
|
||||
|
|
@ -60,14 +62,16 @@ export default {
|
|||
//打开事件
|
||||
this.socket.onopen = function () {
|
||||
this.loading = false;
|
||||
alert("连接成功");
|
||||
//alert("连接成功");
|
||||
ElMessage.success("连接成功!");
|
||||
};
|
||||
this.socket.onerror = (error) => {
|
||||
console.error("WebSocket Error:", error);
|
||||
};
|
||||
//关闭事件
|
||||
this.socket.onclose = function () {
|
||||
alert("连接已关闭!");
|
||||
//alert("连接已关闭!");
|
||||
ElMessage.success("连接已关闭!");
|
||||
router.push("/user");
|
||||
};
|
||||
// 浏览器端收消息,获得从服务端发送过来的文本消息
|
||||
|
|
@ -80,10 +84,6 @@ export default {
|
|||
_this.base64Image = 'data:image/png;base64,'+data.data
|
||||
|
||||
// console.log("收到数据====" + msg.data);
|
||||
} else if (data.type == "offline") {
|
||||
alert("对方已下线");
|
||||
_this.socket.close();
|
||||
router.push("/user");
|
||||
}
|
||||
};
|
||||
}
|
||||
|
|
@ -98,6 +98,9 @@ export default {
|
|||
onUnmounted() {
|
||||
this.socket.close();
|
||||
},
|
||||
beforeUnmount() {
|
||||
this.socket.close();
|
||||
},
|
||||
};
|
||||
</script>
|
||||
<style>
|
||||
|
|
|
|||
|
|
@ -0,0 +1,68 @@
|
|||
<template>
|
||||
<div>
|
||||
<img ref="imagePlayer" alt="实时图像" width="100%" height="100%"/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
imagePlayer: null,
|
||||
socket: null,
|
||||
device_id: localStorage.getItem("realvp_device_id"),
|
||||
tokenData: {
|
||||
token: localStorage.getItem("token"),
|
||||
ip: localStorage.getItem("ip"),
|
||||
userId: localStorage.getItem("userId"),
|
||||
username: localStorage.getItem("username"),
|
||||
to_user_id: this.to_user_id,
|
||||
},
|
||||
};
|
||||
},
|
||||
mounted() {
|
||||
this.imagePlayer = this.$refs.imagePlayer;
|
||||
this.initWebSocket();
|
||||
},
|
||||
methods: {
|
||||
initWebSocket() {
|
||||
let socketUrl =
|
||||
"wss://gep.ljsea.top/device/get_real_time_image?device_id=" + //wss://gep.ljsea.top/device/get_real_time_image?device_id= wss://vps.ljsea.top/tool/video_real_time?device_id=
|
||||
this.device_id +
|
||||
"&token=" +
|
||||
this.tokenData.token;
|
||||
this.socket = new WebSocket(socketUrl);
|
||||
this.socket.onopen = () => {
|
||||
console.log('WebSocket连接成功');
|
||||
};
|
||||
this.socket.onmessage = (event) => {
|
||||
const blob = new Blob([event.data], { type: 'image/jpeg' });
|
||||
const objectURL = URL.createObjectURL(blob);
|
||||
this.imagePlayer.src = objectURL;
|
||||
};
|
||||
this.socket.onclose = () => {
|
||||
console.log('WebSocket连接关闭');
|
||||
this.imagePlayer.src = "";
|
||||
};
|
||||
this.socket.onerror = (error) => {
|
||||
console.error('WebSocket出现错误:', error);
|
||||
};
|
||||
},
|
||||
},
|
||||
beforeUnmount() {
|
||||
if (this.socket) {
|
||||
this.socket.onmessage = null;
|
||||
console.log('关闭WebSocket连接');
|
||||
this.socket.close();
|
||||
window.location.reload();
|
||||
}
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
img {
|
||||
width: 100%;
|
||||
margin: 0 auto;
|
||||
}
|
||||
</style>
|
||||
|
|
@ -0,0 +1,553 @@
|
|||
<script>
|
||||
import axios from "axios";
|
||||
import router from "@/router/index.js";
|
||||
import Cookies from "js-cookie";
|
||||
import { autoResizerProps, ElMessage } from "element-plus";
|
||||
import CryptoJS from "crypto-js";
|
||||
import Menu from "@/views/Menu.vue";
|
||||
|
||||
import { getConfigFileListService } from "@/api/file.js";
|
||||
import { addConfigFileService } from "@/api/file.js";
|
||||
import { deleteConfigFileService } from "@/api/file.js";
|
||||
import { updateConfigFileService } from "@/api/file.js";
|
||||
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
ip: "",
|
||||
tableData: [],
|
||||
search_id: 2002,
|
||||
ConfigFileUpdateForm: {},
|
||||
keyword: "",
|
||||
updateDialogVisible: false,
|
||||
addConfigFileVisible: false,
|
||||
ConfigFileCurrentPageData: [],
|
||||
pageSize: 10,
|
||||
currentPage: 1,
|
||||
upload_file: null, //文件上传
|
||||
file_md5: "", //文件上传的md5
|
||||
addForm: {
|
||||
file_name: "",
|
||||
file_path: "",
|
||||
},
|
||||
loading: false, // 加载状态
|
||||
server_list: [
|
||||
{ label: "js.ljsea.top", value: "js.ljsea.top" },
|
||||
{ label: "tx.ljsea.top", value: "tx.ljsea.top" },
|
||||
{ label: "gep.ljsea.top", value: "gep.ljsea.top" },
|
||||
{ label: "as.ljsea.top", value: "as.ljsea.top" },
|
||||
{ label: 'al.ljsea.top', value: "al.ljsea.top" }
|
||||
],
|
||||
|
||||
role: "",
|
||||
tokenData: {
|
||||
token: localStorage.getItem("token"),
|
||||
ip: localStorage.getItem("ip"),
|
||||
userId: localStorage.getItem("userId"),
|
||||
username: localStorage.getItem("username"),
|
||||
id: 2002,
|
||||
server: localStorage.getItem('config_file_server')||"gep.ljsea.top",
|
||||
keyword: "",
|
||||
},
|
||||
};
|
||||
},
|
||||
|
||||
// methods 是一些用来更改状态与触发更新的函数
|
||||
// 它们可以在模板中作为事件处理器绑定
|
||||
methods: {
|
||||
async getConfigFileList() {
|
||||
this.loading = true;
|
||||
let result = {};
|
||||
try {
|
||||
//判断search_id是字符串还是数字
|
||||
let req = {
|
||||
token: this.tokenData.token,
|
||||
type: "all",
|
||||
};
|
||||
result = await getConfigFileListService(req);
|
||||
let data = result.data;
|
||||
if (data !== undefined && data !== null) {
|
||||
this.tableData = data;
|
||||
}
|
||||
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
ElMessage.error("获取文件列表失败");
|
||||
} finally {
|
||||
this.loading = false;
|
||||
}
|
||||
for(let i = 0;i<this.tableData.length;i++) {
|
||||
this.tableData[i].UpdatedAt = this.formattedTime(this.tableData[i].UpdatedAt);
|
||||
this.tableData[i].CreatedAt = this.formattedTime(this.tableData[i].CreatedAt)
|
||||
//console.log('this.ConfigFileList:',this.ConfigFileList);
|
||||
}
|
||||
this.currentPageData();
|
||||
},
|
||||
addConfigFileV() {
|
||||
this.addConfigFileVisible = true;
|
||||
},
|
||||
handleServerChange() {
|
||||
localStorage.setItem("config_file_server", this.tokenData.server);
|
||||
this.getConfigFileList();
|
||||
},
|
||||
async addConfigFile() {
|
||||
this.loading = true;
|
||||
this.addDialogVisible = false;
|
||||
let result = {};
|
||||
try {
|
||||
let req = {
|
||||
token: this.tokenData.token,
|
||||
file_name: this.addForm.file_name,
|
||||
file_path: this.addForm.file_path,
|
||||
};
|
||||
result = await addConfigFileService(req);
|
||||
if (result.code == 0) {
|
||||
ElMessage.success("添加成功");
|
||||
this.getConfigFileList();
|
||||
this.addConfigFileVidibale = false;
|
||||
} else {
|
||||
ElMessage.error("添加失败");
|
||||
}
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
ElMessage.error("添加配置文件失败");
|
||||
} finally {
|
||||
this.loading = false;
|
||||
}
|
||||
},
|
||||
async deleteConfigFile(index) {
|
||||
// 是否删除
|
||||
let isDelete = confirm("是否删除?");
|
||||
if (!isDelete) {
|
||||
return;
|
||||
}
|
||||
let is_delete_file = confirm("是否删除文件?");
|
||||
|
||||
this.loading = true;
|
||||
let result = {};
|
||||
try {
|
||||
let req = {
|
||||
token: this.tokenData.token,
|
||||
id: this.ConfigFileCurrentPageData[index].ID,
|
||||
del_file: is_delete_file,
|
||||
};
|
||||
result = await deleteConfigFileService(req);
|
||||
if (result.code == 0) {
|
||||
ElMessage.success("删除成功");
|
||||
this.getConfigFileList();
|
||||
} else {
|
||||
ElMessage.error("删除失败");
|
||||
}
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
ElMessage.error("删除配置文件失败");
|
||||
} finally {
|
||||
this.loading = false;
|
||||
}
|
||||
},
|
||||
async updateConfigFile(index) {
|
||||
console.log("index:", index);
|
||||
let cf = this.ConfigFileCurrentPageData[index];
|
||||
let req = {
|
||||
token: this.tokenData.token,
|
||||
id: cf.ID,
|
||||
type: "one",
|
||||
};
|
||||
let result = await getConfigFileListService(req);
|
||||
let data = result.data;
|
||||
this.ConfigFileUpdateForm = data[0];
|
||||
this.updateDialogVisible = true;
|
||||
},
|
||||
handleAvatarFileUpload(e) {
|
||||
this.avatar_file = e.target.files[0];
|
||||
//判断文件类型是否为图片
|
||||
if (!this.avatar_file.type.startsWith("image/")) {
|
||||
ElMessage.error("请选择图片文件");
|
||||
this.avatar_file = null;
|
||||
return;
|
||||
}
|
||||
this.uploadAvatarFile();
|
||||
},
|
||||
readFileAndCalculateMD5() {
|
||||
return new Promise((resolve, reject) => {
|
||||
const reader = new FileReader();
|
||||
reader.onload = (event) => {
|
||||
const wordArray = CryptoJS.lib.WordArray.create(event.target.result);
|
||||
const md5Hash = CryptoJS.MD5(wordArray);
|
||||
const md5Str = md5Hash.toString(CryptoJS.enc.Hex);
|
||||
//console.log("onload: " + md5Str);
|
||||
this.file_md5 = md5Str;
|
||||
resolve(md5Str);
|
||||
};
|
||||
reader.onerror = (error) => {
|
||||
reject(error);
|
||||
};
|
||||
reader.readAsArrayBuffer(this.avatar_file);
|
||||
});
|
||||
},
|
||||
formattedTime(isoTime) {
|
||||
const date = new Date(isoTime);
|
||||
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}`;
|
||||
},
|
||||
async uploadFile() {
|
||||
if (this.avatar_file == null) {
|
||||
alert("请先选择要上传的文件");
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
let result = {};
|
||||
this.file_md5 = await this.readFileAndCalculateMD5(this.avatar_file);
|
||||
//console.log("md5:",this.file_md5);
|
||||
let md5_result = await GetFileInfoByMd5Service({
|
||||
md5: this.file_md5,
|
||||
token: this.tokenData.token,
|
||||
type: 1,
|
||||
});
|
||||
if (md5_result.code === 0) {
|
||||
result = md5_result;
|
||||
} else {
|
||||
let formData = new FormData();
|
||||
formData.append("file", this.avatar_file);
|
||||
//console.log("add file: " + this.file);
|
||||
formData.append("upload_type", "1");
|
||||
formData.append("md5", this.file_md5);
|
||||
formData.append("auth_type", "public");
|
||||
//console.log("formData:",formData);
|
||||
|
||||
result = await UploadFileService(formData, this.tokenData.token);
|
||||
if (result.code !== 0) {
|
||||
ElMessage.error("上传文件失败,请稍后再试");
|
||||
return;
|
||||
}
|
||||
}
|
||||
let resp_data = result.data;
|
||||
|
||||
//console.log("resp:",resp_data);
|
||||
let url = "https://gep.ljsea.top/tool/file/" + resp_data.FileStoreName;
|
||||
|
||||
this.UserUpdateForm.avatar = url;
|
||||
//更新用户信息
|
||||
await this.updateUserInfo();
|
||||
} catch (error) {
|
||||
ElMessage.error("上传文件时出现网络错误,请稍后再试");
|
||||
console.error(error);
|
||||
}
|
||||
},
|
||||
async updateConfigFileInfo() {
|
||||
this.loading = true;
|
||||
let result = {};
|
||||
try {
|
||||
let req = {
|
||||
token: this.tokenData.token,
|
||||
id: this.ConfigFileUpdateForm.id,
|
||||
content: this.ConfigFileUpdateForm.content,
|
||||
};
|
||||
for (var key in this.UserUpdateForm) {
|
||||
req[key] = this.UserUpdateForm[key];
|
||||
}
|
||||
result = await updateConfigFileService(req);
|
||||
if (result.code === 0) {
|
||||
ElMessage.success("更新成功");
|
||||
this.updateDialogVisible = false;
|
||||
} else {
|
||||
ElMessage.error("更新失败");
|
||||
}
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
ElMessage.error("更新配置文件失败");
|
||||
} finally {
|
||||
this.loading = false;
|
||||
}
|
||||
},
|
||||
|
||||
onSubmit() {
|
||||
getConfigFileList();
|
||||
},
|
||||
currentPageData() {
|
||||
this.ConfigFileCurrentPageData = this.tableData.slice(
|
||||
(this.currentPage - 1) * this.pageSize,
|
||||
this.currentPage * this.pageSize
|
||||
);
|
||||
},
|
||||
handleSizeChange(val) {
|
||||
//console.log(`每页 ${val} 条`);
|
||||
this.pageSize = val;
|
||||
this.currentPageData();
|
||||
},
|
||||
handleCurrentChange(val) {
|
||||
//console.log(`当前页: ${val}`);
|
||||
this.currentPage = val;
|
||||
this.currentPageData();
|
||||
},
|
||||
|
||||
async displayMyInfo() {
|
||||
await this.getMyUserInfo(this.tokenData.user_id);
|
||||
this.updateDialogVisible = true;
|
||||
},
|
||||
async displayUserInfo(id) {
|
||||
await this.getMyUserInfo(id);
|
||||
this.updateDialogVisible = true;
|
||||
},
|
||||
|
||||
handleMenuSelect(val) {
|
||||
router.push(val);
|
||||
},
|
||||
toVideoList() {
|
||||
router.push("/videoList");
|
||||
},
|
||||
// 修改条纹颜色
|
||||
tableRowClassName({ row, rowIndex }) {
|
||||
if (row.human === 1) {
|
||||
return {
|
||||
background: "#488aff",
|
||||
};
|
||||
} else {
|
||||
return "";
|
||||
}
|
||||
},
|
||||
},
|
||||
|
||||
// 生命周期钩子会在组件生命周期的各个不同阶段被调用
|
||||
// 例如这个函数就会在组件挂载完成后被调用
|
||||
async mounted() {
|
||||
let now = new Date();
|
||||
if (localStorage.getItem("token") === null) {
|
||||
router.push("/login");
|
||||
}
|
||||
await this.getConfigFileList();
|
||||
//await this.getMyUserInfo(localStorage.getItem("userId"));
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div>
|
||||
<Menu></Menu>
|
||||
<el-container style="height: 700px; border: 1px solid #eee">
|
||||
<el-header style="font-size: 40px; background-color: rgb(238, 241, 246)"
|
||||
>文件</el-header
|
||||
>
|
||||
<el-container>
|
||||
<el-main>
|
||||
<el-form :inline="true" :model="tokenData" class="demo-form-inline">
|
||||
<el-form-item>
|
||||
<el-dialog
|
||||
v-model="updateDialogVisible"
|
||||
title="编辑配置文件"
|
||||
width="60%"
|
||||
:before-close="handleClose"
|
||||
>
|
||||
<!-- 内容主体区域 -->
|
||||
<el-form
|
||||
ref="updateFormRef"
|
||||
:model="ConfigFileUpdateForm"
|
||||
:rules="UserUpdateFormRules"
|
||||
label-width="70px"
|
||||
>
|
||||
<!-- row -->
|
||||
<el-row>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="ID">
|
||||
<el-input
|
||||
v-model="ConfigFileUpdateForm.id"
|
||||
disabled
|
||||
></el-input>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="文件名称">
|
||||
<el-input
|
||||
v-model="ConfigFileUpdateForm.file_name"
|
||||
disabled
|
||||
></el-input>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="32">
|
||||
<el-form-item label="文件路径">
|
||||
<el-input
|
||||
v-model="ConfigFileUpdateForm.file_path"
|
||||
disabled
|
||||
style="width: 512px"
|
||||
></el-input>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col>
|
||||
<el-form-item label="文件内容" prop="device_status">
|
||||
<el-input
|
||||
type="textarea"
|
||||
v-model="ConfigFileUpdateForm.content"
|
||||
style="width: 800px"
|
||||
:autosize="{ minRows: 4, maxRows: 24 }"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</el-form>
|
||||
|
||||
<!-- 底部区域 -->
|
||||
<template #footer>
|
||||
<span class="dialog-footer">
|
||||
<el-button @click="updateDialogVisible = false"
|
||||
>取消</el-button
|
||||
>
|
||||
<el-button type="primary" @click="updateConfigFileInfo()"
|
||||
>确定</el-button
|
||||
>
|
||||
</span>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</el-form-item>
|
||||
|
||||
<!-- 表单 -->
|
||||
<el-form :inline="true" :model="tokenData" class="demo-form-inline">
|
||||
<el-form-item>
|
||||
<el-button
|
||||
class="el-button--danger"
|
||||
type="primary"
|
||||
@click="getConfigFileList()"
|
||||
>查询</el-button
|
||||
>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button
|
||||
class="el-button--danger"
|
||||
type="primary"
|
||||
@click="addConfigFileV()"
|
||||
>添加配置文件</el-button
|
||||
>
|
||||
</el-form-item>
|
||||
<!-- 选择服务器 -->
|
||||
<el-form-item>
|
||||
<el-select
|
||||
v-model="tokenData.server"
|
||||
filterable allow-create
|
||||
@change="handleServerChange"
|
||||
>
|
||||
<el-option v-for="item in server_list" :key="item.value" :label="item.label" :value="item.value"></el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</el-form>
|
||||
|
||||
<el-dialog
|
||||
v-model="addConfigFileVisible"
|
||||
title="添加配置文件"
|
||||
width="50%"
|
||||
:before-close="handleClose"
|
||||
>
|
||||
<!-- 内容主体区域 -->
|
||||
<el-form
|
||||
ref="addFormRef"
|
||||
:model="addForm"
|
||||
:rules="addFormRules"
|
||||
label-width="70px"
|
||||
>
|
||||
<el-row>
|
||||
<el-form-item label="文件名称" prop="file_name">
|
||||
<el-input
|
||||
v-model="addForm.file_name"
|
||||
autocomplete="on"
|
||||
></el-input>
|
||||
</el-form-item>
|
||||
</el-row>
|
||||
<el-row>
|
||||
<el-form-item label="文件路径" prop="file_path">
|
||||
<el-input
|
||||
v-model="addForm.file_path"
|
||||
autocomplete="on"
|
||||
></el-input>
|
||||
</el-form-item>
|
||||
</el-row>
|
||||
</el-form>
|
||||
<!-- 底部区域 -->
|
||||
<template #footer>
|
||||
<span class="dialog-footer">
|
||||
<el-button @click="addConfigFileVidibale = false"
|
||||
>取消</el-button
|
||||
>
|
||||
<el-button type="primary" @click="addConfigFile()"
|
||||
>确定</el-button
|
||||
>
|
||||
</span>
|
||||
</template>
|
||||
</el-dialog>
|
||||
|
||||
<!-- 表格 :row-style="this.tableRowClassName"-->
|
||||
<el-table
|
||||
:data="ConfigFileCurrentPageData"
|
||||
width="100%"
|
||||
v-loading="loading"
|
||||
element-loading-text="加载中..."
|
||||
element-loading-background="rgba(240, 242, 245, 0.8)"
|
||||
>
|
||||
:row-style="this.tableRowClassName"
|
||||
<el-table-column prop="ID" label="id" width="80"></el-table-column>
|
||||
<el-table-column
|
||||
prop="FileName"
|
||||
label="文件名称"
|
||||
width="120"
|
||||
></el-table-column>
|
||||
<el-table-column
|
||||
prop="FilePath"
|
||||
label="文件路径"
|
||||
width="180"
|
||||
></el-table-column>
|
||||
<el-table-column
|
||||
prop="CreatedAt"
|
||||
label="创建时间"
|
||||
width="160"
|
||||
></el-table-column>
|
||||
<el-table-column
|
||||
prop="UpdatedAt"
|
||||
label="上次更新"
|
||||
width="160"
|
||||
></el-table-column>
|
||||
<el-table-column
|
||||
prop="AuthID"
|
||||
label="创建用户ID"
|
||||
width="100"
|
||||
></el-table-column>
|
||||
<el-table-column label="操作" width="200">
|
||||
<template #default="scope">
|
||||
<el-button
|
||||
type="primary"
|
||||
size="mini"
|
||||
@click.prevent="updateConfigFile(scope.$index)"
|
||||
>编辑</el-button
|
||||
>
|
||||
<el-button
|
||||
type="primary"
|
||||
size="mini"
|
||||
@click.prevent="deleteConfigFile(scope.$index)"
|
||||
>删除</el-button
|
||||
>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<!-- 分页条 -->
|
||||
<!-- Pagination 分页 -->
|
||||
<el-pagination
|
||||
background
|
||||
layout="total,sizes, prev, pager, next, jumper"
|
||||
@size-change="handleSizeChange"
|
||||
@current-change="handleCurrentChange"
|
||||
:total="10"
|
||||
></el-pagination>
|
||||
</el-main>
|
||||
</el-container>
|
||||
</el-container>
|
||||
</div>
|
||||
</template>
|
||||
<style scoped>
|
||||
.blueRowbg {
|
||||
background: "#488aff";
|
||||
}
|
||||
</style>
|
||||
|
|
@ -0,0 +1,759 @@
|
|||
<script>
|
||||
import axios from "axios";
|
||||
import { inject } from "vue";
|
||||
import { getGroupListService } from "@/api/group.js";
|
||||
import { updateGroupService } from "@/api/group.js";
|
||||
import { restartDeviceService } from "@/api/device.js";
|
||||
import { addDeviceService } from "@/api/device.js";
|
||||
import {sendMessageService } from "@/api/chat.js";
|
||||
import {getGroupFriendListService } from "@/api/chat.js";
|
||||
import {acceptInviteService } from "@/api/user.js";
|
||||
import { rejectInviteService } from "@/api/user.js";
|
||||
import { getFriendListService } from "@/api/chat.js";
|
||||
import { getGroupUsersListService } from "@/api/chat.js";
|
||||
import { addGroupService} from "@/api/chat.js";
|
||||
import {DelFGService} from "@/api/user.js";
|
||||
import { updateDeviceService } from "@/api/device.js";
|
||||
import router from "@/router/index.js";
|
||||
import { ElMessage } from 'element-plus';
|
||||
import Menu from "@/views/Menu.vue";
|
||||
|
||||
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
ip: "",
|
||||
FriendsTableIsDisplay:false,
|
||||
tableData: [],
|
||||
group_id:0,
|
||||
is_del_group_user:false,
|
||||
GroupRequestIsDisplay : false,
|
||||
GroupRequestList:[],
|
||||
tokenData: {
|
||||
token: localStorage.getItem("token"),
|
||||
ip: localStorage.getItem("ip"),
|
||||
userId: localStorage.getItem("userId"),
|
||||
username: localStorage.getItem("username"),
|
||||
},
|
||||
addDialogVisible: false,
|
||||
updateDialogVisible: false,
|
||||
searchForm: {
|
||||
hour: 0,
|
||||
entrydate: [],
|
||||
},
|
||||
add_groups:[],
|
||||
addForm: {
|
||||
group_name: "",
|
||||
group_info: "",
|
||||
group_type: "",
|
||||
group_icon:"",
|
||||
auth_id: -1,
|
||||
token: localStorage.getItem("token"),
|
||||
},
|
||||
updateForm: {
|
||||
id:0,
|
||||
group_name: "",
|
||||
group_info: "",
|
||||
group_type: "",
|
||||
group_icon:"",
|
||||
auth_id: -1,
|
||||
token: localStorage.getItem("token"),
|
||||
},
|
||||
};
|
||||
},
|
||||
|
||||
// methods 是一些用来更改状态与触发更新的函数
|
||||
// 它们可以在模板中作为事件处理器绑定
|
||||
methods: {
|
||||
async getGroupList() {
|
||||
let result = {};
|
||||
let add_res ={};
|
||||
try {
|
||||
result = await getGroupListService(this.tokenData);
|
||||
add_res = await getFriendListService(this.tokenData);
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
}
|
||||
let data = result.data;
|
||||
let m ={};
|
||||
for(let i=0;i<data.length;i++){
|
||||
m[data[i].ID] = data[i];
|
||||
}
|
||||
let add_resu = add_res.data.groups;
|
||||
let temp =[];
|
||||
for(let i=0;i<add_resu.length;i++){
|
||||
if(m[add_resu[i].ID] === undefined){
|
||||
temp.push(add_resu[i]);
|
||||
}
|
||||
}
|
||||
this.add_groups = temp;
|
||||
|
||||
|
||||
// for(let d in data){
|
||||
// let res = JSON.parse(d);
|
||||
// console.log("res=",res);
|
||||
// this.tableData.push(res);
|
||||
// }
|
||||
// console.log(this.tableData);
|
||||
|
||||
this.tableData = data;
|
||||
},
|
||||
onSubmit() {
|
||||
getGroupList({ token: token });
|
||||
},
|
||||
handleSizeChange() {
|
||||
alert("每页记录数变化" + val);
|
||||
},
|
||||
handleCurrentChange() {
|
||||
alert("页码发生变化" + val);
|
||||
},
|
||||
//获取好友列表
|
||||
async displayFriends(index){
|
||||
this.group_id = this.tableData[index].ID;
|
||||
let result ={}
|
||||
try{
|
||||
result = await getFriendListService(this.tokenData);
|
||||
if(result.code ===0){
|
||||
this.FriendsGList = result.data.friends;
|
||||
this.GroupList=result.data.groups;
|
||||
this.FriendsTableIsDisplay = true;
|
||||
this.is_del_group_user=false;
|
||||
}else{
|
||||
ElMessage.error("获取好友列表失败");
|
||||
}
|
||||
}catch(e){
|
||||
console.log(e);
|
||||
}
|
||||
},
|
||||
async displayGroupUsersInfo(index){
|
||||
this.group_id = this.tableData[index].ID;
|
||||
let result ={}
|
||||
try{
|
||||
let req={
|
||||
token: this.tokenData.token,
|
||||
group_id: this.group_id,
|
||||
}
|
||||
result = await getGroupUsersListService(req);
|
||||
if(result.code ===0){
|
||||
this.FriendsGList = result.data;
|
||||
this.FriendsTableIsDisplay = true;
|
||||
this.is_del_group_user=true;
|
||||
|
||||
}else{
|
||||
ElMessage.error("获取群用户列表失败");
|
||||
}
|
||||
}catch(e){
|
||||
console.log(e);
|
||||
}
|
||||
},
|
||||
|
||||
//邀请好友加入群组
|
||||
async inviteUser(index) {
|
||||
var id = this.tableData[index].ID;
|
||||
var restart_data = {
|
||||
id: id,
|
||||
option: "one",
|
||||
ip: this.ip,
|
||||
userId: this.tokenData.userId,
|
||||
token: this.tokenData.token,
|
||||
};
|
||||
try {
|
||||
var d_re = await restartDeviceService(restart_data);
|
||||
if (d_re.code == 0) {
|
||||
ElMessage.success('重启成功');
|
||||
} else {
|
||||
alert("操作失败");
|
||||
ElMessage.fail('操作失败');
|
||||
}
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
}
|
||||
},
|
||||
|
||||
async deleteGroup(index) {
|
||||
var id = this.tableData[index].ID;
|
||||
var delete_data = {
|
||||
group_id: id,
|
||||
type:3,//删除群组
|
||||
userId: this.tokenData.userId,
|
||||
token: this.tokenData.token,
|
||||
};
|
||||
try {
|
||||
var d_re = await DelFGService(delete_data);
|
||||
if (d_re.code == 0) {
|
||||
//alert("删除成功");
|
||||
ElMessage.success('删除成功');
|
||||
//刷新页面
|
||||
this.getGroupList();
|
||||
} else {
|
||||
//alert("操作失败");
|
||||
ElMessage.fail("操作失败");
|
||||
}
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
}
|
||||
},
|
||||
async updateButtonGroup(index) {
|
||||
var id = this.tableData[index].ID;
|
||||
this.group_id = id;
|
||||
this.updateForm.group_name = this.tableData[index].GroupName;
|
||||
this.updateForm.group_info = this.tableData[index].GroupInfo;
|
||||
this.updateForm.group_type = this.tableData[index].GroupType;
|
||||
this.updateForm.group_icon = this.tableData[index].GroupIcon;
|
||||
this.updateForm.auth_id = this.tableData[index].AuthID;
|
||||
this.updateForm.id = id;
|
||||
this.updateDialogVisible= true;
|
||||
},
|
||||
async addGroup() {
|
||||
this.addDialogVisible = false;
|
||||
let result = {};
|
||||
try {
|
||||
result = await addGroupService(this.addForm);
|
||||
if (result.code == 0) {
|
||||
ElMessage.success("添加成功");
|
||||
this.getGroupList();
|
||||
} else {
|
||||
//alert("添加失败");
|
||||
ElMessage.error("添加失败")
|
||||
}
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
}
|
||||
},
|
||||
async updateGroup() {
|
||||
this.updateDialogVisible = false;
|
||||
let result = {};
|
||||
try {
|
||||
result = await updateGroupService(this.updateForm);
|
||||
if (result.code == 0) {
|
||||
//alert("修改成功");
|
||||
ElMessage.success("修改成功");
|
||||
this.getGroupList();
|
||||
} else {
|
||||
alert("修改失败");
|
||||
}
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
}
|
||||
},
|
||||
|
||||
async inviteFriendAddGroup(index){
|
||||
var id = this.FriendsGList[index].id;
|
||||
let req={
|
||||
token: localStorage.getItem("token"),
|
||||
ip: localStorage.getItem("ip"),
|
||||
userId: localStorage.getItem("userId"),
|
||||
username: localStorage.getItem("username"),
|
||||
from_user_id:localStorage.getItem("userId"),
|
||||
to_user_id:id,
|
||||
group_id:this.group_id,
|
||||
msg:this.currentMsg,
|
||||
type:6,
|
||||
}
|
||||
try {
|
||||
var d_re = await sendMessageService(req);
|
||||
if (d_re.code == 0) {
|
||||
//alert("邀请成功");
|
||||
ElMessage.success("邀请成功");
|
||||
} else {
|
||||
//alert("操作失败");
|
||||
ElMessage.error("操作失败:"+d_re.error);
|
||||
}
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
}
|
||||
},
|
||||
async delGroupUser(index){
|
||||
var id = this.FriendsGList[index].id;
|
||||
let req={
|
||||
token: localStorage.getItem("token"),
|
||||
from_user_id: localStorage.getItem("userId"),
|
||||
to_user_id: id,
|
||||
group_id: this.group_id,
|
||||
msg: "踢出群聊",
|
||||
type: 4,
|
||||
}
|
||||
if (id === parseInt(req.userId)){
|
||||
ElMessage.error("不能删除自己,若自己要退出,请解散群聊!")
|
||||
return
|
||||
}
|
||||
try {
|
||||
var d_re = await DelFGService(req);
|
||||
if (d_re.code == 0) {
|
||||
//alert("邀请成功");
|
||||
ElMessage.success("删除成功");
|
||||
} else {
|
||||
//alert("操作失败");
|
||||
ElMessage.error("操作失败:"+d_re.error);
|
||||
}
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
}
|
||||
},
|
||||
async getIpClient() {
|
||||
try {
|
||||
const response = await axios.get("https://ipinfo.io/json");
|
||||
this.ip = response.data.ip;
|
||||
localStorage.setItem("ip", this.ip);
|
||||
//console.log(response);
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
}
|
||||
},
|
||||
async displayGroupReq(){
|
||||
let result ={}
|
||||
try{
|
||||
let req={
|
||||
token:this.tokenData.token,
|
||||
type:1
|
||||
}
|
||||
result =await getGroupFriendListService(req)
|
||||
if(result.code ===0){
|
||||
this.GroupRequestList = result.data;
|
||||
this.GroupRequestIsDisplay = true;
|
||||
}else{
|
||||
ElMessage.error("获取好友请求列表失败");
|
||||
}
|
||||
}catch(e){
|
||||
console.log(e);
|
||||
}
|
||||
|
||||
},
|
||||
//退出群聊
|
||||
async DelFriendsOrGroup(index){
|
||||
// 删除前确认
|
||||
if (!confirm("确定退出吗?")) {
|
||||
return;
|
||||
}
|
||||
var id = this.add_groups[index].ID;
|
||||
|
||||
let result ={}
|
||||
try{
|
||||
result =await DelFGService({
|
||||
token: localStorage.getItem("token"),
|
||||
from_user_id: localStorage.getItem("userId"),
|
||||
to_user_id: id,
|
||||
group_id: id,
|
||||
msg: "退出群聊",
|
||||
type: 2,
|
||||
});
|
||||
if(result.code ===0){
|
||||
ElMessage.success("退出群聊成功");
|
||||
this.getGroupList();
|
||||
}else{
|
||||
ElMessage.error("退出群聊失败");
|
||||
}
|
||||
}catch(e){
|
||||
console.log(e);
|
||||
}
|
||||
},
|
||||
async AcceptFriendsOrGroup(index){
|
||||
var id = this.GroupRequestList[index].id;
|
||||
var im_id = this.GroupRequestList[index].im_id;
|
||||
let result ={}
|
||||
try{
|
||||
result =await acceptInviteService({
|
||||
token: localStorage.getItem("token"),
|
||||
id: im_id,
|
||||
from_user_id: localStorage.getItem("userId"),
|
||||
to_user_id: id,
|
||||
group_id: this.GroupRequestList[index].group_id,
|
||||
msg: "接受加入群组请求",
|
||||
index: 1,
|
||||
type: 2,
|
||||
});
|
||||
if(result.code ===0){
|
||||
ElMessage.success("接受请求成功");
|
||||
this.displayGroupReq();
|
||||
}else{
|
||||
ElMessage.error("接受请求失败");
|
||||
}
|
||||
}catch(e){
|
||||
console.log(e);
|
||||
}
|
||||
},
|
||||
async RefuseFriendsOrGroup(index){
|
||||
var id = this.GroupRequestList[index].id;
|
||||
var im_id = this.GroupRequestList[index].im_id;
|
||||
let result ={}
|
||||
try{
|
||||
result =await rejectInviteService({
|
||||
token: localStorage.getItem("token"),
|
||||
id: im_id,
|
||||
from_user_id: localStorage.getItem("userId"),
|
||||
to_user_id: id,
|
||||
group_id: this.GroupRequestList[index].group_id,
|
||||
msg: "接受加入群组请求",
|
||||
index: 1,
|
||||
type: 2,
|
||||
});
|
||||
if(result.code ===0){
|
||||
ElMessage.success("接受请求成功");
|
||||
this.displayGroupReq();
|
||||
}else{
|
||||
ElMessage.error("接受请求失败");
|
||||
}
|
||||
}catch(e){
|
||||
console.log(e);
|
||||
}
|
||||
},
|
||||
handleMenuSelect(val) {
|
||||
router.push(val);
|
||||
},
|
||||
toVideoList() {
|
||||
router.push("/videoList");
|
||||
},
|
||||
// 修改条纹颜色
|
||||
tableRowClassName({ row, rowIndex }) {
|
||||
if (row.human === 1) {
|
||||
return {
|
||||
background: "#488aff",
|
||||
};
|
||||
} else {
|
||||
return "";
|
||||
}
|
||||
},
|
||||
},
|
||||
|
||||
// 生命周期钩子会在组件生命周期的各个不同阶段被调用
|
||||
// 例如这个函数就会在组件挂载完成后被调用
|
||||
async mounted() {
|
||||
let now = new Date();
|
||||
if (localStorage.getItem("token") === null) {
|
||||
router.push("/login");
|
||||
}
|
||||
// console.log("mounted");
|
||||
this.getIpClient();
|
||||
this.getGroupList();
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div>
|
||||
<Menu></Menu>
|
||||
<el-container style="height: 700px; border: 1px solid #eee">
|
||||
<el-header style="font-size: 40px; background-color: rgb(238, 241, 246)"
|
||||
>群组</el-header
|
||||
>
|
||||
<el-container>
|
||||
<el-main>
|
||||
<!-- 表单 -->
|
||||
<el-form :inline="true" :model="tokenData" class="demo-form-inline">
|
||||
<el-form-item>
|
||||
<el-button
|
||||
class="el-button--danger"
|
||||
type="primary"
|
||||
@click="getGroupList()"
|
||||
>查询</el-button
|
||||
>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button type="primary" @click="addDialogVisible = true"
|
||||
>建群</el-button
|
||||
>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button type="primary" @click="displayGroupReq()"
|
||||
>请求加入群聊请求</el-button
|
||||
>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-dialog
|
||||
v-model="addDialogVisible"
|
||||
title="建群"
|
||||
width="50%"
|
||||
:before-close="handleClose"
|
||||
>
|
||||
<!-- 内容主体区域 -->
|
||||
<el-form
|
||||
ref="addFormRef"
|
||||
:model="addForm"
|
||||
:rules="addFormRules"
|
||||
label-width="70px"
|
||||
>
|
||||
<el-form-item label="名称" prop="device_name">
|
||||
<el-input
|
||||
v-model="addForm.group_name"
|
||||
autocomplete="on"
|
||||
></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="描述" prop="info">
|
||||
<el-input v-model="addForm.group_info"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="类型" prop="type">
|
||||
<el-input v-model="addForm.group_type"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="icon" prop="device_info">
|
||||
<el-input v-model="addForm.group_icon"></el-input>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<!-- 底部区域 -->
|
||||
<template #footer>
|
||||
<span class="dialog-footer">
|
||||
<el-button @click="addDialogVisible = false"
|
||||
>取消</el-button
|
||||
>
|
||||
<el-button type="primary" @click="addGroup()"
|
||||
>确定</el-button
|
||||
>
|
||||
</span>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item>
|
||||
<el-dialog
|
||||
v-model="updateDialogVisible"
|
||||
title="修改群信息"
|
||||
width="50%"
|
||||
:before-close="handleClose"
|
||||
>
|
||||
<!-- 内容主体区域 -->
|
||||
<el-form
|
||||
ref="updateFormRef"
|
||||
:model="updateForm"
|
||||
:rules="updateFormRules"
|
||||
label-width="70px"
|
||||
>
|
||||
<el-form-item label="名称" prop="group_name">
|
||||
<el-input
|
||||
v-model="updateForm.group_name"
|
||||
autocomplete="on"
|
||||
></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="群信息" prop="group_info">
|
||||
<el-input v-model="updateForm.group_info"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="群类型" prop="group_type">
|
||||
<el-input v-model="updateForm.group_type"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="群Icon" prop="group_icon">
|
||||
<el-input v-model="updateForm.group_icon"></el-input>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<!-- 底部区域 -->
|
||||
<template #footer>
|
||||
<span class="dialog-footer">
|
||||
<el-button @click="updateDialogVisible = false"
|
||||
>取消</el-button
|
||||
>
|
||||
<el-button type="primary" @click="updateGroup()"
|
||||
>确定</el-button
|
||||
>
|
||||
</span>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
|
||||
<el-dialog
|
||||
title="成员列表"
|
||||
width="40%"
|
||||
v-model="FriendsTableIsDisplay"
|
||||
center>
|
||||
|
||||
<el-table :data="FriendsGList" width="100%">
|
||||
<el-table-column prop="id" label="id" width="80"></el-table-column>
|
||||
<el-table-column
|
||||
prop="name"
|
||||
label="名称"
|
||||
width="100"
|
||||
></el-table-column>
|
||||
<el-table-column
|
||||
prop="email"
|
||||
label="用户邮箱"
|
||||
width="180"
|
||||
></el-table-column>
|
||||
<el-table-column>
|
||||
<template #default="scope">
|
||||
<el-button
|
||||
type="primary"
|
||||
size="mini"
|
||||
@click.prevent="inviteFriendAddGroup(scope.$index)"
|
||||
v-if="is_del_group_user === false"
|
||||
>邀请</el-button
|
||||
>
|
||||
<el-button
|
||||
type="primary"
|
||||
size="mini"
|
||||
@click.prevent="delGroupUser(scope.$index)"
|
||||
v-if="is_del_group_user === true"
|
||||
>删除</el-button
|
||||
>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</el-dialog>
|
||||
|
||||
<el-dialog
|
||||
title="加入群组请求"
|
||||
width="50%"
|
||||
v-model="GroupRequestIsDisplay"
|
||||
center>
|
||||
|
||||
<el-table :data="GroupRequestList" width="100%">
|
||||
<el-table-column prop="id" label="id" width="80"></el-table-column>
|
||||
<el-table-column
|
||||
prop="name"
|
||||
label="名称"
|
||||
width="100"
|
||||
></el-table-column>
|
||||
<el-table-column
|
||||
prop="email"
|
||||
label="用户邮箱"
|
||||
width="180"
|
||||
></el-table-column>
|
||||
<el-table-column
|
||||
prop="group_id"
|
||||
label="群id"
|
||||
width="180"
|
||||
></el-table-column>
|
||||
<el-table-column>
|
||||
<template #default="scope">
|
||||
<el-button
|
||||
type="primary"
|
||||
size="mini"
|
||||
@click.prevent="AcceptFriendsOrGroup(scope.$index)"
|
||||
>同意请求</el-button
|
||||
>
|
||||
<el-button
|
||||
type="primary"
|
||||
size="mini"
|
||||
@click.prevent="RefuseFriendsOrGroup(scope.$index)"
|
||||
>拒绝请求</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</el-dialog>
|
||||
|
||||
<h>
|
||||
我建的群组
|
||||
</h>
|
||||
<!-- 表格 :row-style="this.tableRowClassName"-->
|
||||
<el-table :data="tableData" width="100%" border>
|
||||
:row-style="this.tableRowClassName"
|
||||
<el-table-column prop="ID" label="id" width="80"></el-table-column>
|
||||
<el-table-column
|
||||
prop="GroupName"
|
||||
label="名称"
|
||||
width="100"
|
||||
></el-table-column>
|
||||
<el-table-column
|
||||
prop="GroupInfo"
|
||||
label="描述"
|
||||
width="180"
|
||||
></el-table-column>
|
||||
<el-table-column
|
||||
prop="GroupType"
|
||||
label="类型"
|
||||
width="120"
|
||||
></el-table-column>
|
||||
<el-table-column
|
||||
prop="CreatedAt"
|
||||
label="创建时间"
|
||||
width="120"
|
||||
></el-table-column>
|
||||
<el-table-column
|
||||
prop="UpdatedAt"
|
||||
label="更新时间"
|
||||
width="120"
|
||||
></el-table-column>
|
||||
<el-table-column label="操作" width="350">
|
||||
<template #default="scope">
|
||||
<el-button
|
||||
type="primary"
|
||||
size="mini"
|
||||
@click.prevent="displayFriends(scope.$index)"
|
||||
>邀请</el-button
|
||||
>
|
||||
<el-button
|
||||
type="primary"
|
||||
size="mini"
|
||||
@click.prevent="displayGroupUsersInfo(scope.$index)"
|
||||
>成员管理</el-button
|
||||
>
|
||||
<el-button
|
||||
type="primary"
|
||||
size="mini"
|
||||
@click.prevent="updateButtonGroup(scope.$index)"
|
||||
>修改</el-button
|
||||
>
|
||||
<el-button
|
||||
type="primary"
|
||||
size="mini"
|
||||
@click.prevent="deleteGroup(scope.$index)"
|
||||
>删除</el-button
|
||||
>
|
||||
<!-- <el-button type="danger" size="mini">删除</el-button> -->
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<br />
|
||||
|
||||
<h>
|
||||
我加入的群组列表
|
||||
</h>
|
||||
|
||||
<!-- 表格 :row-style="this.tableRowClassName"-->
|
||||
<el-table :data="add_groups" width="100%" border>
|
||||
:row-style="this.tableRowClassName"
|
||||
<el-table-column prop="ID" label="id" width="80"></el-table-column>
|
||||
<el-table-column
|
||||
prop="GroupName"
|
||||
label="名称"
|
||||
width="100"
|
||||
></el-table-column>
|
||||
<el-table-column
|
||||
prop="GroupInfo"
|
||||
label="描述"
|
||||
width="180"
|
||||
></el-table-column>
|
||||
<el-table-column
|
||||
prop="GroupType"
|
||||
label="类型"
|
||||
width="120"
|
||||
></el-table-column>
|
||||
<el-table-column
|
||||
prop="CreatedAt"
|
||||
label="创建时间"
|
||||
width="120"
|
||||
></el-table-column>
|
||||
<el-table-column
|
||||
prop="UpdatedAt"
|
||||
label="更新时间"
|
||||
width="120"
|
||||
></el-table-column>
|
||||
<el-table-column label="操作" width="350">
|
||||
<template #default="scope">
|
||||
<el-button
|
||||
type="primary"
|
||||
size="mini"
|
||||
@click.prevent="DelFriendsOrGroup(scope.$index)"
|
||||
>退出群聊</el-button
|
||||
>
|
||||
<!-- <el-button type="danger" size="mini">删除</el-button> -->
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<br />
|
||||
|
||||
<!-- 分页条 -->
|
||||
<!-- Pagination 分页 -->
|
||||
<!-- <el-pagination
|
||||
background
|
||||
layout="total,sizes, prev, pager, next, jumper"
|
||||
@size-change="handleSizeChange"
|
||||
@current-change="handleCurrentChange"
|
||||
:total="1000"
|
||||
></el-pagination> -->
|
||||
</el-main>
|
||||
</el-container>
|
||||
</el-container>
|
||||
</div>
|
||||
</template>
|
||||
<style>
|
||||
.blueRowbg {
|
||||
background: "#488aff";
|
||||
}
|
||||
</style>
|
||||
|
|
@ -55,6 +55,7 @@ import router from "@/router/index.js";
|
|||
import * as crypto from "crypto";
|
||||
import CryptoJS from "crypto-js";
|
||||
import { ElLoading } from "element-plus";
|
||||
import { ElMessage } from 'element-plus';
|
||||
import Cookies from "js-cookie";
|
||||
export default {
|
||||
data() {
|
||||
|
|
@ -142,7 +143,11 @@ export default {
|
|||
if (this.cnt > 10) {
|
||||
//暂停定时器
|
||||
this.stopInterval();
|
||||
alert("连接失败,请重试!");
|
||||
//alert("连接失败,请重试!");
|
||||
ElMessage({
|
||||
message: "连接失败,请重试!",
|
||||
type: "error",
|
||||
})
|
||||
router.push("/user");
|
||||
}
|
||||
return;
|
||||
|
|
@ -168,7 +173,8 @@ export default {
|
|||
if (this.cnt > 30) {
|
||||
//暂停定时器
|
||||
this.stopInterval();
|
||||
confirm("连接失败,请重试!");
|
||||
//confirm("连接失败,请重试!");
|
||||
ElMessage.error("连接失败,请重试!");
|
||||
router.push("/user");
|
||||
}
|
||||
}
|
||||
|
|
@ -272,7 +278,7 @@ export default {
|
|||
} else {
|
||||
console.log("浏览器支持WebSocket");
|
||||
let socketUrl =
|
||||
"wss://gep.ljsea.xyz/im/ws?to_user_id=" +
|
||||
"wss://tx.ljsea.top/im/ws?to_user_id=" +
|
||||
this.to_user_id +
|
||||
"&token=" +
|
||||
this.tokenData.token;
|
||||
|
|
@ -287,21 +293,29 @@ export default {
|
|||
//打开事件
|
||||
this.socket.onopen = function () {
|
||||
this.loading=false
|
||||
alert("连接成功");
|
||||
//alert("连接成功");
|
||||
ElMessage({
|
||||
message: "连接成功",
|
||||
type: "success",
|
||||
})
|
||||
};
|
||||
this.socket.onerror = (error) => {
|
||||
console.error("WebSocket Error:", error);
|
||||
};
|
||||
//关闭事件
|
||||
this.socket.onclose = function () {
|
||||
alert("连接已关闭!");
|
||||
//alert("连接已关闭!");
|
||||
ElMessage({
|
||||
message: "连接已关闭",
|
||||
type: "error",
|
||||
})
|
||||
router.push("/user");
|
||||
};
|
||||
// 浏览器端收消息,获得从服务端发送过来的文本消息
|
||||
this.socket.onmessage = async function (msg) {
|
||||
//console.log("收到数据====" + msg.data);
|
||||
let data = JSON.parse(msg.data); // 对收到的json数据进行解析, 类似这样的:
|
||||
console.log("收到数据====" + data);
|
||||
//console.log("收到数据====" + data);
|
||||
// 如果服务器端发送过来的json数据
|
||||
if (data.type == "msg") { // 如果是消息类型,解密消息内容
|
||||
data.data = await _this.decryptAES(
|
||||
|
|
@ -314,7 +328,11 @@ export default {
|
|||
// 构建消息内容
|
||||
_this.createContent(_this.to_user_name, null, data.data);
|
||||
}else if (data.type == "offline"){
|
||||
alert("对方已下线");
|
||||
//alert("对方已下线");
|
||||
ElMessage({
|
||||
message: "对方已下线",
|
||||
type: "error",
|
||||
})
|
||||
_this.socket.close();
|
||||
router.push("/user");
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,120 +1,105 @@
|
|||
<template>
|
||||
<el-row class="loginPage">
|
||||
<!-- element-plus login form -->
|
||||
<el-form
|
||||
ref="form"
|
||||
size="large"
|
||||
autocomplete="false"
|
||||
:model="loginData"
|
||||
:rules="rules"
|
||||
v-if="isLogin === true"
|
||||
>
|
||||
<el-form-item>
|
||||
<h1>登录</h1>
|
||||
</el-form-item>
|
||||
<div class="login-bg">
|
||||
<div class="login-container">
|
||||
<div class="login-header">
|
||||
<img class="logo mr10" src="../assets/img/logo.svg" alt="" />
|
||||
<div class="login-title">综合系统</div>
|
||||
</div>
|
||||
<el-form :model="param" :rules="rules" ref="login" size="large">
|
||||
<el-form-item prop="username">
|
||||
<el-input
|
||||
placeholder="请输入用户名或邮箱"
|
||||
v-model="loginData.username"
|
||||
></el-input>
|
||||
<el-input v-model="param.username" placeholder="用户名或邮箱">
|
||||
<template #prepend>
|
||||
<el-icon>
|
||||
<User />
|
||||
</el-icon>
|
||||
</template>
|
||||
</el-input>
|
||||
</el-form-item>
|
||||
<el-form-item prop="password">
|
||||
<el-input
|
||||
placeholder="请输入密码"
|
||||
type="password"
|
||||
v-model="loginData.password"
|
||||
></el-input>
|
||||
placeholder="密码"
|
||||
v-model="param.password"
|
||||
@keyup.enter="submitForm(login)"
|
||||
>
|
||||
<template #prepend>
|
||||
<el-icon>
|
||||
<Lock />
|
||||
</el-icon>
|
||||
</template>
|
||||
</el-input>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<!-- <div class="pwd-tips">
|
||||
<el-checkbox class="pwd-checkbox" v-model="checked" label="记住密码" />
|
||||
<el-link type="primary" @click="$router.push('/reset-pwd')">忘记密码</el-link>
|
||||
</div> -->
|
||||
<el-button
|
||||
class="button"
|
||||
class="login-btn"
|
||||
type="primary"
|
||||
auto-insert-space
|
||||
@click="login"
|
||||
size="large"
|
||||
@click="onLogin"
|
||||
>登录</el-button
|
||||
>
|
||||
</el-form-item>
|
||||
<el-form-item class="flex">
|
||||
<el-link @click="isLogin = false"> 注册 </el-link>
|
||||
</el-form-item>
|
||||
<!-- <p class="login-text">
|
||||
没有账号?<el-link type="primary" @click="$router.push('/register')">立即注册</el-link>
|
||||
</p> -->
|
||||
</el-form>
|
||||
|
||||
<!-- element-plus register form -->
|
||||
<el-form
|
||||
ref="form"
|
||||
size="large"
|
||||
autocomplete="false"
|
||||
:model="registerData"
|
||||
:rules="rules"
|
||||
v-if="isLogin === false"
|
||||
>
|
||||
<el-form-item>
|
||||
<h1>注册</h1>
|
||||
</el-form-item>
|
||||
<el-form-item prop="username">
|
||||
<el-input
|
||||
placeholder="请输入用户名"
|
||||
v-model="registerData.username"
|
||||
></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item prop="email">
|
||||
<el-input
|
||||
placeholder="请输入邮箱"
|
||||
v-model="registerData.email"
|
||||
></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item prop="password">
|
||||
<el-input
|
||||
placeholder="请输入密码"
|
||||
type="password"
|
||||
v-model="registerData.password"
|
||||
></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item prop="password">
|
||||
<el-input
|
||||
placeholder="请再次输入密码"
|
||||
type="password"
|
||||
v-model="registerData.repassword"
|
||||
></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button type="primary" @click="onRegister" auto-insert-space
|
||||
>注册</el-button
|
||||
>
|
||||
</el-form-item>
|
||||
<el-form-item class="flex">
|
||||
<el-link @click="isLogin = true"> 返回 </el-link>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</el-row>
|
||||
<div>
|
||||
<div>二维码状态: {{ qr_status }}</div>
|
||||
<canvas ref="qrCodeCanvas"></canvas>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref, onMounted, inject, onUnmounted } from "vue";
|
||||
import axios from "axios";
|
||||
import {
|
||||
getQRService,
|
||||
getUUIDService,
|
||||
loginService,
|
||||
registerService,
|
||||
} from "@/api/user.js";
|
||||
import router from "@/router/index.js";
|
||||
import VueQr from "vue-qr"; // 确保你已经注册了这个组件
|
||||
import QRCode from "qrcode";
|
||||
import { ref, reactive, inject, onMounted } from "vue";
|
||||
import { useRouter } from "vue-router";
|
||||
import { ElMessage } from "element-plus";
|
||||
import { loginService } from "@/api/user.js";
|
||||
import { GetUserInfoService } from "@/api/user.js";
|
||||
|
||||
const isLogin = ref(true);
|
||||
const qrCodeCanvas = ref(null);
|
||||
// 从本地存储获取登录参数
|
||||
const lgStr = localStorage.getItem("login-param");
|
||||
const defParam = lgStr ? JSON.parse(lgStr) : null;
|
||||
const globalData = inject("globalData");
|
||||
// 记住密码状态
|
||||
const checked = ref(lgStr ? true : false);
|
||||
|
||||
// 创建一个响应式引用来存储定时器ID
|
||||
const intervalId = ref(null);
|
||||
var uuid = "";
|
||||
const router = useRouter();
|
||||
// 登录表单数据
|
||||
const param = reactive({
|
||||
username: defParam ? defParam.username : "",
|
||||
password: defParam ? defParam.password : "",
|
||||
});
|
||||
|
||||
onMounted(async () => {
|
||||
// 保存登录参数到本地存储
|
||||
let res = await getMyUserInfo(localStorage.getItem("userId"));
|
||||
if(res.code === 0){
|
||||
// 如果已经登录,跳转到用户页面
|
||||
router.push("/user");
|
||||
}else{
|
||||
window.location.href = "https://sv.ljsea.top/#/login?site=gs-vp"; //https://sv.ljsea.top/
|
||||
}
|
||||
});
|
||||
|
||||
// 表单验证规则
|
||||
const rules = {
|
||||
username: [
|
||||
{
|
||||
required: true,
|
||||
message: "请输入用户名",
|
||||
trigger: "blur",
|
||||
},
|
||||
],
|
||||
password: [
|
||||
{
|
||||
required: true,
|
||||
message: "请输入密码",
|
||||
trigger: "blur",
|
||||
},
|
||||
],
|
||||
};
|
||||
// 表单引用
|
||||
const login = ref(null);
|
||||
|
||||
const qr_status = ref("未被扫描");
|
||||
//表单数据
|
||||
var loginData = ref({
|
||||
username: "",
|
||||
|
|
@ -123,218 +108,119 @@ var loginData = ref({
|
|||
ip: "",
|
||||
});
|
||||
|
||||
const registerData = ref({
|
||||
username: "",
|
||||
email: "",
|
||||
password: "",
|
||||
repassword: "",
|
||||
});
|
||||
|
||||
//表单校验规则
|
||||
const rules = {
|
||||
password: [
|
||||
{ required: true, message: "请输入密码", trigger: "blur" },
|
||||
{
|
||||
min: 6,
|
||||
max: 20,
|
||||
message: "密码长度在 6 到 20 个字符",
|
||||
trigger: "blur",
|
||||
},
|
||||
],
|
||||
username: [
|
||||
{ required: true, message: "请输入用户名", trigger: "blur" },
|
||||
{
|
||||
min: 5,
|
||||
max: 20,
|
||||
message: "用户名长度在 6 到 20 个字符",
|
||||
trigger: "blur",
|
||||
},
|
||||
],
|
||||
email: [{}],
|
||||
};
|
||||
onMounted(() => {
|
||||
init();
|
||||
startInterval();
|
||||
const token = localStorage.getItem("token");
|
||||
if (token !== null) {
|
||||
isLogin.value = true; // 更新登录状态
|
||||
router.push("/videoList"); // 跳转到视频列表页面
|
||||
// 你可以在这里获取 UID 并更新 uid.value
|
||||
}
|
||||
});
|
||||
onUnmounted(() => {
|
||||
stopInterval();
|
||||
});
|
||||
|
||||
// 开启定时器
|
||||
const startInterval = () => {
|
||||
if (intervalId.value) {
|
||||
// 如果定时器已经开启,则不执行任何操作
|
||||
return;
|
||||
}
|
||||
intervalId.value = setInterval(getQRStatus, 2000);
|
||||
};
|
||||
|
||||
// 关闭定时器
|
||||
const stopInterval = () => {
|
||||
if (intervalId.value) {
|
||||
clearInterval(intervalId.value);
|
||||
intervalId.value = null; // 清除引用中的定时器ID
|
||||
}
|
||||
};
|
||||
|
||||
const creatQrCode = async () => {
|
||||
console.log("creatQrCode:", uuid);
|
||||
var qrcode = new qrcode(this.$refs.qrCodeUrl, {
|
||||
text: uuid, // 需要转换为二维码的内容
|
||||
width: 100,
|
||||
height: 100,
|
||||
colorDark: "#000000",
|
||||
colorLight: "#ffffff",
|
||||
correctLevel: QRCode.CorrectLevel.H,
|
||||
});
|
||||
};
|
||||
|
||||
//登录接口调用
|
||||
const login = async () => {
|
||||
const onLogin = async () => {
|
||||
console.log("params:", param);
|
||||
|
||||
loginData.value.username = param.username;
|
||||
loginData.value.password = param.password;
|
||||
loginData.value.fingerprint = "cc913e1ef0c3a6fd2a5e5b55a7063e46";
|
||||
let result = await loginService(loginData);
|
||||
globalData.token = result.data;
|
||||
localStorage.setItem("token", result.data.token);
|
||||
localStorage.setItem("userId", result.data.id);
|
||||
localStorage.setItem("username", result.data.username);
|
||||
let now = new Date();
|
||||
localStorage.setItem("end_time", now.setDate(now.getHours() + 12)); //过期时间
|
||||
//token.value= result.data;
|
||||
router.push("/videoList");
|
||||
};
|
||||
|
||||
//注册接口调用
|
||||
const onRegister = async () => {
|
||||
//校验密码是否一致
|
||||
if (registerData.value.password !== registerData.value.repassword) {
|
||||
alert("两次密码不一致");
|
||||
console.log("login result:", result);
|
||||
if (result.code !== 0) {
|
||||
//alert(result.message);
|
||||
ElMessage.error("登录失败!用户名或密码错误");
|
||||
return;
|
||||
}
|
||||
//校验邮箱是否合法
|
||||
let email = registerData.value.email;
|
||||
let reg = /^(\w-*\.*)+@(\w-?)+(\.\w{2,})+$/;
|
||||
if (!reg.test(email)) {
|
||||
alert("邮箱格式不正确");
|
||||
return;
|
||||
}
|
||||
|
||||
let result = await registerService(registerData);
|
||||
if (result !== null) {
|
||||
globalData.token = result.data;
|
||||
localStorage.setItem("token", result.data.token);
|
||||
localStorage.setItem("userId", result.data.id);
|
||||
localStorage.setItem("token", result.data.access_token);
|
||||
localStorage.setItem("userId", result.data.user_id);
|
||||
localStorage.setItem("username", result.data.username);
|
||||
let now = new Date();
|
||||
localStorage.setItem("end_time", now.setDate(now.getHours() + 12)); //过期时间
|
||||
localStorage.setItem("refresh_token", result.data.refresh_token);
|
||||
|
||||
await getMyUserInfo(result.data.user_id);
|
||||
//token.value= result.data;
|
||||
router.push("/videoList");
|
||||
}
|
||||
};
|
||||
|
||||
const generateQRCode = () => {
|
||||
// 假设我们有一个数据字符串要转换为二维码
|
||||
const data = uuid;
|
||||
// 确保 canvas 已经被渲染到 DOM 中
|
||||
if (qrCodeCanvas.value) {
|
||||
const canvas = qrCodeCanvas.value;
|
||||
const ctx = canvas.getContext("2d");
|
||||
|
||||
// 设置 canvas 的大小
|
||||
canvas.width = 256;
|
||||
canvas.height = 256;
|
||||
|
||||
// 使用 qrcode 库生成二维码
|
||||
QRCode.toCanvas(
|
||||
canvas,
|
||||
data,
|
||||
{
|
||||
width: 256,
|
||||
height: 256,
|
||||
color: {
|
||||
dark: "#000000",
|
||||
light: "#ffffff",
|
||||
},
|
||||
},
|
||||
function (error) {
|
||||
if (error) console.error(error);
|
||||
console.log("二维码已生成");
|
||||
}
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
const getUUID = async () => {
|
||||
const getMyUserInfo = async (id) => {
|
||||
let result = {};
|
||||
try {
|
||||
const response = await getUUIDService({
|
||||
device: "windows",
|
||||
address: localStorage.getItem("address"),
|
||||
ip: localStorage.getItem("ip"),
|
||||
});
|
||||
uuid = response.data.toString();
|
||||
let uid = uuid.toString();
|
||||
//await creatQrCode(uid);
|
||||
generateQRCode(uuid);
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
let tokenData = {
|
||||
token: localStorage.getItem("token"),
|
||||
id: id,
|
||||
};
|
||||
result = await GetUserInfoService(tokenData);
|
||||
if (result.code === 0) {
|
||||
//console.log("token data:",this.tokenData)
|
||||
localStorage.setItem("video_func", result.data.VideoFunc > 0 ? "true" : "false");
|
||||
localStorage.setItem("device_func", result.data.DeviceFunc > 0 ? "true" : "false");
|
||||
localStorage.setItem("cid_func", result.data.CIDFunc > 0 ? "true" : "false");
|
||||
localStorage.setItem("role", result.data.Role === "admin" ? "admin" : "user");
|
||||
//alert("video_func:" + localStorage.getItem("video_func")+" type:" +typeof(localStorage.getItem("video_func")));
|
||||
router.push("/user");
|
||||
}
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
}
|
||||
return result;
|
||||
};
|
||||
|
||||
const getQRStatus = async () => {
|
||||
let result = await getQRService({ uuid: uuid });
|
||||
if (result.code === 0) {
|
||||
if (result.data === "0") {
|
||||
} else if (result.data === "1") {
|
||||
qr_status.value = "等待确认";
|
||||
} else {
|
||||
globalData.token = result.data;
|
||||
localStorage.setItem("token", result.data.token);
|
||||
localStorage.setItem("userId", result.data.id);
|
||||
localStorage.setItem("username", result.data.username);
|
||||
let now = new Date();
|
||||
localStorage.setItem("end_time", now.setDate(now.getHours() + 12)); //过期时间
|
||||
//token.value= result.data;
|
||||
router.push("/videoList");
|
||||
}
|
||||
} else {
|
||||
alert(result.message);
|
||||
}
|
||||
};
|
||||
|
||||
const getIpClient = async () => {
|
||||
try {
|
||||
const response = await axios.get("https://ip.zxinc.org/api.php?type=json");
|
||||
loginData.value.ip = response.data.data.myip;
|
||||
localStorage.setItem("ip", response.data.data.myip);
|
||||
localStorage.setItem("city", response.data.data.country);
|
||||
localStorage.setItem("address", response.data.data.location);
|
||||
// console.log("ip:",response.data.ip);
|
||||
// console.log("login ip:",loginData.ip);
|
||||
// console.log(response.data);
|
||||
// console.log(loginData);
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
}
|
||||
};
|
||||
const init = async () => {
|
||||
getIpClient();
|
||||
await getUUID();
|
||||
};
|
||||
const register = async () => {
|
||||
let result = registerService(registerData.value);
|
||||
if (result.code === 0) {
|
||||
alert(result.message);
|
||||
} else {
|
||||
alert(result.message);
|
||||
}
|
||||
};
|
||||
// 获取标签存储并清空标签
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
canvas {
|
||||
border: 1px solid #000;
|
||||
.login-bg {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
width: 100%;
|
||||
height: 100vh;
|
||||
/* background: url(../assets/img/login-bg.jpg) center/cover no-repeat; */
|
||||
}
|
||||
|
||||
.login-header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
margin-bottom: 40px;
|
||||
}
|
||||
|
||||
.logo {
|
||||
width: 35px;
|
||||
}
|
||||
|
||||
.login-title {
|
||||
font-size: 22px;
|
||||
color: #333;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.login-container {
|
||||
width: 450px;
|
||||
border-radius: 5px;
|
||||
background: #fff;
|
||||
padding: 40px 50px 50px;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.pwd-tips {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
font-size: 14px;
|
||||
margin: -10px 0 10px;
|
||||
color: #787878;
|
||||
}
|
||||
|
||||
.pwd-checkbox {
|
||||
height: auto;
|
||||
}
|
||||
|
||||
.login-btn {
|
||||
display: block;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.login-tips {
|
||||
font-size: 12px;
|
||||
color: #999;
|
||||
}
|
||||
|
||||
.login-text {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
margin-top: 20px;
|
||||
font-size: 14px;
|
||||
color: #787878;
|
||||
}
|
||||
</style>
|
||||
|
|
@ -0,0 +1,107 @@
|
|||
<template>
|
||||
<el-button
|
||||
v-if="func_permissions.video"
|
||||
type="primary"
|
||||
size="mini"
|
||||
@click.prevent="handleMenuSelect('/videoList')"
|
||||
>视频列表</el-button
|
||||
>
|
||||
<el-button
|
||||
v-if="func_permissions.device"
|
||||
type="primary"
|
||||
size="mini"
|
||||
@click.prevent="handleMenuSelect('/device')"
|
||||
>设备管理</el-button
|
||||
>
|
||||
<el-button
|
||||
v-if="func_permissions.cid"
|
||||
type="primary"
|
||||
size="mini"
|
||||
@click.prevent="handleMenuSelect('/cid')"
|
||||
>集成部署</el-button
|
||||
>
|
||||
<el-button
|
||||
v-if="func_permissions.role"
|
||||
type="primary"
|
||||
size="mini"
|
||||
@click.prevent="handleMenuSelect('/file')"
|
||||
>文件</el-button
|
||||
>
|
||||
<el-button
|
||||
v-if="func_permissions.role"
|
||||
type="primary"
|
||||
size="mini"
|
||||
@click.prevent="handleMenuSelect('/shell')"
|
||||
>执行命令</el-button
|
||||
>
|
||||
<el-button
|
||||
type="primary"
|
||||
size="mini"
|
||||
@click.prevent="handleMenuSelect('/User')"
|
||||
>用户</el-button
|
||||
>
|
||||
<el-button
|
||||
type="primary"
|
||||
size="mini"
|
||||
@click.prevent="handleMenuSelect('/chat')"
|
||||
>聊天</el-button
|
||||
>
|
||||
<el-button
|
||||
type="primary"
|
||||
size="mini"
|
||||
@click.prevent="handleMenuSelect('/group')"
|
||||
>群组</el-button
|
||||
>
|
||||
<el-button
|
||||
type="primary"
|
||||
size="mini"
|
||||
@click.prevent="handleMenuSelect('/projectSelect')"
|
||||
>项目选择</el-button
|
||||
>
|
||||
<el-button
|
||||
type="primary"
|
||||
size="mini"
|
||||
class="el-button--danger"
|
||||
@click="logout()"
|
||||
>退出登录</el-button
|
||||
>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { GetUserInfoService } from "@/api/user.js";
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
tokenData: {
|
||||
token: localStorage.getItem("token"),
|
||||
ip: localStorage.getItem("ip"),
|
||||
userId: localStorage.getItem("userId"),
|
||||
username: localStorage.getItem("username"),
|
||||
id: 2002,
|
||||
keyword: "",
|
||||
},
|
||||
func_permissions: {
|
||||
video: localStorage.getItem("video_func") === "true", //string转为boolean
|
||||
device: localStorage.getItem("device_func") === "true", //string转为boolean
|
||||
cid: localStorage.getItem("cid_func") === "true", //string转为boolean
|
||||
role: localStorage.getItem("role") === "admin", //string转为boolean
|
||||
},
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
handleMenuSelect(path) {
|
||||
//this.getMyUserInfo();
|
||||
this.$router.push(path);
|
||||
},
|
||||
logout() {
|
||||
//询问是否退出登录
|
||||
if (!confirm("确定退出登录吗?")) {
|
||||
return;
|
||||
}
|
||||
//退出登录
|
||||
localStorage.clear();
|
||||
this.$router.push("/login");
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
|
@ -0,0 +1,724 @@
|
|||
<script>
|
||||
import router from "@/router/index.js";
|
||||
import { ElMessage } from "element-plus";
|
||||
import Menu from "@/views/Menu.vue";
|
||||
|
||||
import { getConfigShellListService } from "@/api/shell.js";
|
||||
import { addConfigShellService } from "@/api/shell.js";
|
||||
import { deleteConfigShellService } from "@/api/shell.js";
|
||||
import { updateConfigShellService } from "@/api/shell.js";
|
||||
import { GetMonitorDeviceInfoService } from "@/api/tool.js";
|
||||
import { UpdateMonitorDeviceInfoService } from "@/api/tool.js";
|
||||
import { DelMonitorDeviceInfoService } from "@/api/tool.js";
|
||||
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
ip: "",
|
||||
tableData: [],
|
||||
loading: false,
|
||||
search_id: 2002,
|
||||
dialogVisible: false,
|
||||
ConfigShellUpdateForm: {},
|
||||
keyword: "",
|
||||
updateDialogVisible: false,
|
||||
addConfigFileVisible: false,
|
||||
ConfigFileCurrentPageData: [],
|
||||
pageSize: 10,
|
||||
currentPage: 1,
|
||||
upload_file: null, //文件上传
|
||||
file_md5: "", //文件上传的md5
|
||||
addForm: {
|
||||
shell_name: "",
|
||||
shel_content: "",
|
||||
server:""
|
||||
},
|
||||
serverList: [
|
||||
{ label: "家里服务器", value: "home_server" },
|
||||
{ label: "腾讯服务器", value: "tx_vp_server" },
|
||||
// { label: "阿里云服务器", value: "aliyun_vp_server" },
|
||||
{ label:"azure服务器", value:"azure_vp_server" },
|
||||
{ label: '阿里云成都服务器', value: "aliyun_chengdu_vp_server"}
|
||||
],
|
||||
monitor_list: [],
|
||||
monitor_add_update_visible: false,
|
||||
monitor_update_add: {},
|
||||
|
||||
|
||||
role: "",
|
||||
tokenData: {
|
||||
token: localStorage.getItem("token"),
|
||||
ip: localStorage.getItem("ip"),
|
||||
userId: localStorage.getItem("userId"),
|
||||
username: localStorage.getItem("username"),
|
||||
id: 2002,
|
||||
server: "gep.ljsea.top",
|
||||
keyword: "",
|
||||
},
|
||||
};
|
||||
},
|
||||
|
||||
// methods 是一些用来更改状态与触发更新的函数
|
||||
// 它们可以在模板中作为事件处理器绑定
|
||||
methods: {
|
||||
async getConfigFileList() {
|
||||
let result = {};
|
||||
this.loading = true;
|
||||
try {
|
||||
//判断search_id是字符串还是数字
|
||||
let req = {
|
||||
token: this.tokenData.token,
|
||||
type: "all",
|
||||
};
|
||||
result = await getConfigShellListService(req);
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
} finally {
|
||||
this.loading = false;
|
||||
}
|
||||
let data = result.data;
|
||||
if (data !== undefined && data !== null) {
|
||||
this.tableData = data;
|
||||
}
|
||||
for(let i = 0;i<this.tableData.length;i++) {
|
||||
this.tableData[i].UpdatedAt = this.formattedTime(this.tableData[i].UpdatedAt);
|
||||
this.tableData[i].CreatedAt = this.formattedTime(this.tableData[i].CreatedAt)
|
||||
//console.log('this.ConfigFileList:',this.ConfigFileList);
|
||||
}
|
||||
|
||||
this.currentPageData();
|
||||
},
|
||||
addConfigFileV() {
|
||||
this.addConfigFileVisible = true;
|
||||
},
|
||||
handleServerChange() {
|
||||
localStorage.setItem("config_file_server", this.tokenData.server);
|
||||
this.getConfigFileList();
|
||||
},
|
||||
async addConfigFile() {
|
||||
this.addDialogVisible = false;
|
||||
let result = {};
|
||||
try {
|
||||
let req = {
|
||||
token: this.tokenData.token,
|
||||
shell_name: this.addForm.shell_name,
|
||||
shell_content: this.addForm.shell_content,
|
||||
server: this.addForm.server
|
||||
};
|
||||
result = await addConfigShellService(req);
|
||||
if (result.code == 0) {
|
||||
ElMessage.success("添加成功");
|
||||
this.getConfigFileList();
|
||||
this.addConfigFileVisible = false;
|
||||
} else {
|
||||
//alert("添加失败");
|
||||
ElMessage.error("添加失败");
|
||||
}
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
}
|
||||
},
|
||||
async updateConfigShellInfo() {
|
||||
let result = {};
|
||||
try {
|
||||
let d={}
|
||||
// for (var key in this.ConfigShellUpdateForm) {
|
||||
// d[key] = this.ConfigShellUpdateForm[key];
|
||||
// }
|
||||
let req = {
|
||||
token: this.tokenData.token,
|
||||
shells: [{"id":this.ConfigShellUpdateForm.ID,"shell_result":this.ConfigShellUpdateForm.ShellResult,"status":this.ConfigShellUpdateForm.Status}],
|
||||
};
|
||||
result = await updateConfigShellService(req);
|
||||
if (result.code === 0) {
|
||||
ElMessage.success("更新成功");
|
||||
this.updateDialogVisible = false;
|
||||
} else {
|
||||
ElMessage.error("更新失败");
|
||||
}
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
}
|
||||
},
|
||||
async deleteConfigFile(index) {
|
||||
// 是否删除
|
||||
let isDelete = confirm("是否删除?");
|
||||
if (!isDelete) {
|
||||
return;
|
||||
}
|
||||
|
||||
let result = {};
|
||||
try {
|
||||
let req = {
|
||||
token: this.tokenData.token,
|
||||
shells: [{"id":this.ConfigFileCurrentPageData[index].ID}],
|
||||
};
|
||||
console.log("req:", req);
|
||||
result = await deleteConfigShellService(req);
|
||||
if (result.code == 0) {
|
||||
ElMessage.success("删除成功");
|
||||
this.getConfigFileList();
|
||||
} else {
|
||||
ElMessage.error("删除失败");
|
||||
}
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
}
|
||||
},
|
||||
formattedTime(isoTime) {
|
||||
const date = new Date(isoTime);
|
||||
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}`;
|
||||
},
|
||||
async updateConfigShell(index) {
|
||||
//console.log("index:", index);
|
||||
let cf = this.ConfigFileCurrentPageData[index];
|
||||
// console.log("cf:", cf);
|
||||
// let req = {
|
||||
// token: this.tokenData.token,
|
||||
// id: cf.ID,
|
||||
// type: "one",
|
||||
// };
|
||||
// let result = await getConfigShellListService(req);
|
||||
// let data = result.data;
|
||||
this.ConfigShellUpdateForm = cf;
|
||||
this.updateDialogVisible = true;
|
||||
},
|
||||
showMonitorList() {
|
||||
this.dialogVisible = true;
|
||||
this.getMonitorDeviceList();
|
||||
},
|
||||
async createAgain(index) {
|
||||
let cf = this.ConfigFileCurrentPageData[index];
|
||||
this.addForm.shell_name = cf.ShellName;
|
||||
this.addForm.shell_content = cf.ShellContent;
|
||||
this.addForm.server = cf.Server;
|
||||
|
||||
await this.addConfigFile();
|
||||
|
||||
},
|
||||
|
||||
onSubmit() {
|
||||
getConfigFileList();
|
||||
},
|
||||
currentPageData() {
|
||||
this.ConfigFileCurrentPageData = this.tableData.slice(
|
||||
(this.currentPage - 1) * this.pageSize,
|
||||
this.currentPage * this.pageSize
|
||||
);
|
||||
},
|
||||
handleSizeChange(val) {
|
||||
//console.log(`每页 ${val} 条`);
|
||||
this.pageSize = val;
|
||||
this.currentPageData();
|
||||
},
|
||||
handleCurrentChange(val) {
|
||||
//console.log(`当前页: ${val}`);
|
||||
this.currentPage = val;
|
||||
this.currentPageData();
|
||||
},
|
||||
|
||||
async displayMyInfo() {
|
||||
await this.getMyUserInfo(this.tokenData.user_id);
|
||||
this.updateDialogVisible = true;
|
||||
},
|
||||
async displayUserInfo(id) {
|
||||
await this.getMyUserInfo(id);
|
||||
this.updateDialogVisible = true;
|
||||
},
|
||||
|
||||
handleMenuSelect(val) {
|
||||
router.push(val);
|
||||
},
|
||||
toVideoList() {
|
||||
router.push("/videoList");
|
||||
},
|
||||
async getMonitorDeviceList(){
|
||||
try {
|
||||
let req = {
|
||||
token: this.tokenData.token,
|
||||
type: "all",
|
||||
};
|
||||
let result = await GetMonitorDeviceInfoService(req);
|
||||
if (result.code === 0) {
|
||||
this.monitor_list = result.data;
|
||||
console.log("monitor_list:", this.monitor_list);
|
||||
this.dialogVisible = true; // 打开设备监控对话框
|
||||
} else {
|
||||
ElMessage.error("获取设备列表失败");
|
||||
}
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
}
|
||||
},
|
||||
updateMonitorShow(index) {
|
||||
this.monitor_add_update_visible = true;
|
||||
this.monitor_update_add = { ...this.monitor_list[index] }; // 深拷贝,避免直接修改原数据
|
||||
},
|
||||
//确定添加或修改设备
|
||||
async addUpdateMonitor(){
|
||||
let req = {
|
||||
"token": this.tokenData.token,
|
||||
"devices": [this.monitor_update_add],
|
||||
};
|
||||
req.devices[0].expire =parseInt(req.devices[0].expire);
|
||||
try{
|
||||
let result = await UpdateMonitorDeviceInfoService(req);
|
||||
if (result.code === 0) {
|
||||
ElMessage.success("设备信息更新成功");
|
||||
this.monitor_add_update_visible = false;
|
||||
} else {
|
||||
ElMessage.error("设备信息更新失败");
|
||||
}
|
||||
|
||||
}catch (e) {
|
||||
console.log(e);
|
||||
}
|
||||
},
|
||||
|
||||
async DelMonitor(index) {
|
||||
let isDelete = confirm("是否删除?");
|
||||
if (!isDelete) {
|
||||
return;
|
||||
}
|
||||
let req = {
|
||||
token: this.tokenData.token,
|
||||
devices: [this.monitor_list[index]],
|
||||
};
|
||||
try {
|
||||
|
||||
let result = await DelMonitorDeviceInfoService(req);
|
||||
if (result.code === 0) {
|
||||
ElMessage.success("设备删除成功");
|
||||
this.getMonitorDeviceList();
|
||||
} else {
|
||||
ElMessage.error("设备删除失败");
|
||||
}
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
// 修改条纹颜色
|
||||
tableRowClassName({ row, rowIndex }) {
|
||||
switch (row.Status) {
|
||||
case 0:
|
||||
return 'rgba(243, 243, 248, 0.1)'; // 浅蓝色
|
||||
case 1:
|
||||
return 'rgba(0, 0, 255, 0.5)'; // 中等深度蓝色
|
||||
case 2:
|
||||
return 'rgba(0, 0, 255, 0.9)'; // 深蓝色
|
||||
default:
|
||||
return 'transparent'; // 默认透明
|
||||
}
|
||||
},
|
||||
},
|
||||
|
||||
// 生命周期钩子会在组件生命周期的各个不同阶段被调用
|
||||
// 例如这个函数就会在组件挂载完成后被调用
|
||||
async mounted() {
|
||||
let now = new Date();
|
||||
if (localStorage.getItem("token") === null) {
|
||||
router.push("/login");
|
||||
}
|
||||
await this.getConfigFileList();
|
||||
//await this.getMyUserInfo(localStorage.getItem("userId"));
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div>
|
||||
<Menu></Menu>
|
||||
<el-container style="height: 700px; border: 1px solid #eee">
|
||||
<el-header style="font-size: 40px; background-color: rgb(238, 241, 246)"
|
||||
>命令分发</el-header
|
||||
>
|
||||
<el-container>
|
||||
<el-main>
|
||||
<el-form :inline="true" :model="tokenData" class="demo-form-inline">
|
||||
<el-form-item>
|
||||
<el-dialog
|
||||
v-model="updateDialogVisible"
|
||||
title="编辑配置"
|
||||
width="60%"
|
||||
:before-close="handleClose"
|
||||
>
|
||||
<!-- 内容主体区域 -->
|
||||
<el-form
|
||||
ref="updateFormRef"
|
||||
:model="ConfigShellUpdateForm"
|
||||
:rules="UserUpdateFormRules"
|
||||
label-width="70px"
|
||||
>
|
||||
<!-- row -->
|
||||
<el-row>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="ID">
|
||||
<el-input
|
||||
v-model="ConfigShellUpdateForm.ID"
|
||||
disabled
|
||||
></el-input>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="名称">
|
||||
<el-input
|
||||
v-model="ConfigShellUpdateForm.ShellName"
|
||||
disabled
|
||||
></el-input>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="32">
|
||||
<el-form-item label="内容">
|
||||
<el-input
|
||||
v-model="ConfigShellUpdateForm.ShellContent"
|
||||
disabled
|
||||
type="textarea"
|
||||
style="width: 512px"
|
||||
></el-input>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col>
|
||||
<el-form-item label="运行结果" prop="shell_result">
|
||||
<el-input
|
||||
type="textarea"
|
||||
v-model="ConfigShellUpdateForm.ShellResult"
|
||||
style="width: 600px"
|
||||
:autosize="{ minRows: 4, maxRows: 8 }"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</el-form>
|
||||
|
||||
<!-- 底部区域 -->
|
||||
<template #footer>
|
||||
<span class="dialog-footer">
|
||||
<el-button @click="updateDialogVisible = false"
|
||||
>取消</el-button
|
||||
>
|
||||
<el-button type="primary" @click="updateConfigShellInfo()"
|
||||
>确定</el-button
|
||||
>
|
||||
</span>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</el-form-item>
|
||||
|
||||
<!-- 表单 -->
|
||||
<el-form :inline="true" :model="tokenData" class="demo-form-inline">
|
||||
<el-form-item>
|
||||
<el-button
|
||||
class="el-button--danger"
|
||||
type="primary"
|
||||
:disabled="loading"
|
||||
@click="getConfigFileList()"
|
||||
>查询</el-button
|
||||
>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button
|
||||
class="el-button--danger"
|
||||
type="primary"
|
||||
@click="addConfigFileV()"
|
||||
>创建命令</el-button
|
||||
>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button
|
||||
class="el-button--danger"
|
||||
type="primary"
|
||||
@click="getMonitorDeviceList()"
|
||||
>设备监控</el-button
|
||||
>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</el-form>
|
||||
|
||||
<el-dialog
|
||||
v-model="addConfigFileVisible"
|
||||
title="创建命令"
|
||||
width="50%"
|
||||
:before-close="handleClose"
|
||||
>
|
||||
<!-- 内容主体区域 -->
|
||||
<el-form
|
||||
ref="addFormRef"
|
||||
:model="addForm"
|
||||
:rules="addFormRules"
|
||||
label-width="70px"
|
||||
>
|
||||
<el-row>
|
||||
<el-form-item label="名称" prop="shell_name">
|
||||
<el-input
|
||||
v-model="addForm.shell_name"
|
||||
autocomplete="on"
|
||||
></el-input>
|
||||
</el-form-item>
|
||||
</el-row>
|
||||
<el-row>
|
||||
<el-form-item label="内容" prop="file_path">
|
||||
<el-input
|
||||
type="textarea"
|
||||
v-model="addForm.shell_content"
|
||||
autocomplete="on"
|
||||
style="width: 600px"
|
||||
:autosize="{ minRows: 4, maxRows: 8 }"
|
||||
></el-input>
|
||||
</el-form-item>
|
||||
</el-row>
|
||||
<el-row>
|
||||
<el-form-item label="服务器" prop="server">
|
||||
<el-select v-model="addForm.server" filterable allow-create>
|
||||
<el-option
|
||||
v-for="item in serverList"
|
||||
:key="item.value"
|
||||
:label="item.label"
|
||||
:value="item.value"
|
||||
></el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-row>
|
||||
</el-form>
|
||||
<!-- 底部区域 -->
|
||||
<template #footer>
|
||||
<span class="dialog-footer">
|
||||
<el-button @click="addConfigFileVisible = false"
|
||||
>取消</el-button
|
||||
>
|
||||
<el-button type="primary" @click="addConfigFile()"
|
||||
>确定</el-button
|
||||
>
|
||||
</span>
|
||||
</template>
|
||||
</el-dialog>
|
||||
|
||||
|
||||
<el-dialog
|
||||
v-model="monitor_add_update_visible"
|
||||
title="编辑监控"
|
||||
width="50%"
|
||||
@close="handleClose">
|
||||
|
||||
<el-form
|
||||
ref="monitorUpdateFormRef"
|
||||
:model="monitor_update_add"
|
||||
:rules="UserUpdateFormRules"
|
||||
label-width="70px"
|
||||
>
|
||||
|
||||
<el-row>
|
||||
<el-form-item label="设备" prop="id">
|
||||
<el-input
|
||||
v-model="monitor_update_add.id"
|
||||
></el-input>
|
||||
</el-form-item>
|
||||
</el-row>
|
||||
<el-row>
|
||||
<el-form-item label="状态" prop="status">
|
||||
<el-select v-model="monitor_update_add.status">
|
||||
<el-option label="在线" value="1"></el-option>
|
||||
<el-option label="离线" value="0"></el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-row>
|
||||
<el-row>
|
||||
<el-form-item label="过期时间" prop="expire">
|
||||
<el-input
|
||||
v-model="monitor_update_add.expire"
|
||||
oninput="this.value = this.value.replace(/[^0-9]/g, '')"
|
||||
></el-input>
|
||||
</el-form-item>
|
||||
</el-row>
|
||||
</el-form>
|
||||
<!-- 底部区域 -->
|
||||
<template #footer>
|
||||
|
||||
<span class="dialog-footer">
|
||||
<el-button @click="monitor_add_update_visible = false"
|
||||
>取消</el-button
|
||||
>
|
||||
<el-button type="primary" @click="addUpdateMonitor()"
|
||||
>确定</el-button
|
||||
>
|
||||
</span>
|
||||
</template>
|
||||
</el-dialog>
|
||||
|
||||
|
||||
<el-dialog
|
||||
v-model="dialogVisible"
|
||||
title="设备状态监控"
|
||||
width="50%"
|
||||
@close="handleClose"
|
||||
>
|
||||
<el-button type="primary" @click="monitor_add_update_visible = true">添加</el-button>
|
||||
<el-table
|
||||
:data="monitor_list"
|
||||
stripe
|
||||
width="90%"
|
||||
fit
|
||||
>
|
||||
<el-table-column prop="id" label="设备" width="150"></el-table-column>
|
||||
<el-table-column prop="status" label="状态" width="150">
|
||||
<template #default="scope">
|
||||
<el-tag
|
||||
:type="scope.row.status === '1' ? 'success' : 'danger'"
|
||||
>{{ scope.row.status === "1" ? '在线' : '离线' }}</el-tag
|
||||
>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="expire" label="过期时间" width="150">
|
||||
</el-table-column>
|
||||
<el-table-column label="操作" width="270">
|
||||
<template #default="scope">
|
||||
<el-button
|
||||
type="primary"
|
||||
size="mini"
|
||||
@click.prevent="updateMonitorShow(scope.$index)"
|
||||
>编辑</el-button
|
||||
>
|
||||
<el-button
|
||||
type="primary"
|
||||
size="mini"
|
||||
@click.prevent="DelMonitor(scope.$index)"
|
||||
>删除</el-button
|
||||
>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<template #footer>
|
||||
<el-button @click="dialogVisible = false">取消</el-button>
|
||||
</template>
|
||||
</el-dialog>
|
||||
|
||||
<!-- 表格 :row-style="this.tableRowClassName"-->
|
||||
<el-table :data="ConfigFileCurrentPageData" width="100%" v-loading="loading">
|
||||
:row-style="tableRowClassName"
|
||||
<el-table-column prop="ID" label="id" width="80"></el-table-column>
|
||||
<el-table-column
|
||||
prop="ShellName"
|
||||
label="命令名称"
|
||||
width="120"
|
||||
></el-table-column>
|
||||
<el-table-column
|
||||
prop="ShellContent"
|
||||
label="命令内容"
|
||||
show-overflow-tooltip
|
||||
width="120"
|
||||
></el-table-column>
|
||||
<el-table-column
|
||||
prop="Status"
|
||||
label="状态"
|
||||
width="100"
|
||||
>
|
||||
<template #default="scope">
|
||||
<el-tag
|
||||
v-if="scope.row.Status === 0"
|
||||
>任务提交</el-tag
|
||||
>
|
||||
<el-tag
|
||||
v-if="scope.row.Status === 1"
|
||||
type="warning"
|
||||
>正在运行</el-tag>
|
||||
<el-tag
|
||||
v-if="scope.row.Status === 2"
|
||||
type="success"
|
||||
>执行成功</el-tag>
|
||||
<el-tag
|
||||
v-if="scope.row.Status === 3"
|
||||
type="danger"
|
||||
>执行出错</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
prop="ShellRuntime"
|
||||
label="SR"
|
||||
width="50"
|
||||
>
|
||||
<template #default="scope">
|
||||
<!-- 转为秒两位小数-->
|
||||
{{ Math.round(scope.row.ShellRuntime * 100) / 100 }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
prop="ShellDuration"
|
||||
label="SD"
|
||||
width="50"
|
||||
>
|
||||
<template #default="scope">
|
||||
<!-- 转为秒两位小数-->
|
||||
{{ Math.round(scope.row.ShellDuration * 100) / 100 }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
<el-table-column
|
||||
prop="Server"
|
||||
label="服务器"
|
||||
width="100"
|
||||
></el-table-column>
|
||||
<el-table-column
|
||||
prop="CreatedAt"
|
||||
label="创建时间"
|
||||
width="160"
|
||||
></el-table-column>
|
||||
<el-table-column
|
||||
prop="UpdatedAt"
|
||||
label="上次更新"
|
||||
width="160"
|
||||
></el-table-column>
|
||||
<!-- <el-table-column
|
||||
prop="AuthID"
|
||||
label="创建用户ID"
|
||||
width="40"
|
||||
></el-table-column> -->
|
||||
<el-table-column label="操作" width="270">
|
||||
<template #default="scope">
|
||||
<el-button
|
||||
type="primary"
|
||||
size="mini"
|
||||
@click.prevent="updateConfigShell(scope.$index)"
|
||||
>编辑</el-button
|
||||
>
|
||||
<el-button
|
||||
type="primary"
|
||||
size="mini"
|
||||
@click.prevent="deleteConfigFile(scope.$index)"
|
||||
>删除</el-button
|
||||
>
|
||||
<el-button
|
||||
type="primary"
|
||||
size="mini"
|
||||
@click.prevent="createAgain(scope.$index)"
|
||||
>再次执行</el-button
|
||||
>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<!-- 分页条 -->
|
||||
<!-- Pagination 分页 -->
|
||||
<el-pagination
|
||||
background
|
||||
layout="total,sizes, prev, pager, next, jumper"
|
||||
@size-change="handleSizeChange"
|
||||
@current-change="handleCurrentChange"
|
||||
:total="tableData.length"
|
||||
></el-pagination>
|
||||
</el-main>
|
||||
</el-container>
|
||||
</el-container>
|
||||
</div>
|
||||
</template>
|
||||
<style>
|
||||
.blueRowbg {
|
||||
background: "#488aff";
|
||||
}
|
||||
</style>
|
||||
|
|
@ -1,15 +1,44 @@
|
|||
<script>
|
||||
import axios from "axios";
|
||||
import { SearchUserService } from "@/api/user.js";
|
||||
import { getFriendReqService } from "@/api/chat.js";
|
||||
import {updateUserInfoService} from "@/api/user.js";
|
||||
import {acceptInviteService } from "@/api/user.js";
|
||||
import { rejectInviteService } from "@/api/user.js";
|
||||
import { addGroupRequestService } from "@/api/user.js";
|
||||
import {GetUserInfoService} from "@/api/user.js";
|
||||
import { GetRedisInfoService } from "@/api/tool.js";
|
||||
import {DelFGService} from "@/api/user.js";
|
||||
import router from "@/router/index.js";
|
||||
import { UploadFileService } from "@/api/tool.js";
|
||||
import {GetFileInfoByMd5Service } from "@/api/tool.js";
|
||||
import Cookies from "js-cookie";
|
||||
import { getFriendListService } from "@/api/chat.js";
|
||||
import {sendMessageService} from "@/api/chat.js";
|
||||
import { ElMessage } from 'element-plus';
|
||||
import CryptoJS from 'crypto-js';
|
||||
import Menu from "@/views/Menu.vue";
|
||||
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
ip: "",
|
||||
tableData: [],
|
||||
search_id: 2002,
|
||||
UserUpdateForm:{},
|
||||
keyword: "",
|
||||
FriendsRequestIsDisplay:false,
|
||||
updateDialogVisible: false,
|
||||
FriendsGRequestList:[],
|
||||
FriendsTableIsDisplay:false,
|
||||
RedisIsDisplay:false,
|
||||
avatar_file: null,
|
||||
file_md5: "",
|
||||
RedisList:[],
|
||||
FriendsGList:[],
|
||||
GroupList:[],
|
||||
groups:[],
|
||||
role: "",
|
||||
tokenData: {
|
||||
token: localStorage.getItem("token"),
|
||||
ip: localStorage.getItem("ip"),
|
||||
|
|
@ -27,8 +56,23 @@ export default {
|
|||
async getUserList() {
|
||||
let result = {};
|
||||
try {
|
||||
this.tokenData.id = this.search_id;
|
||||
//判断search_id是字符串还是数字
|
||||
if(isNaN(this.search_id)){
|
||||
//是字符串,说明是关键字
|
||||
this.keyword = this.search_id;
|
||||
this.tokenData.id = -1;
|
||||
this.tokenData.keyword = this.keyword;
|
||||
}else if(isFinite(this.search_id)){
|
||||
//是数字,说明是ID
|
||||
this.tokenData.id = this.search_id;
|
||||
this.tokenData.keyword = "";
|
||||
}else{
|
||||
//不是数字也不是字符串
|
||||
ElMessage.error("输入错误,请输入数字或者关键字");
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
Cookies.set("search_id", this.search_id);
|
||||
Cookies.set("keyword", this.keyword);
|
||||
result = await SearchUserService(this.tokenData);
|
||||
|
|
@ -37,6 +81,261 @@ export default {
|
|||
}
|
||||
let data = result.data;
|
||||
this.tableData = data;
|
||||
this.groups= result.group;
|
||||
},
|
||||
async setUserPermission(index) {
|
||||
var id = this.tableData[index].ID;
|
||||
await this.displayUserInfo(id);
|
||||
},
|
||||
async requestFriend(index) {
|
||||
var id = this.tableData[index].ID;
|
||||
var name = this.tableData[index].Name;
|
||||
let result ={}
|
||||
try{
|
||||
result =await sendMessageService({
|
||||
token: localStorage.getItem("token"),
|
||||
from_user_id: localStorage.getItem("userId"),
|
||||
to_user_id: id,
|
||||
msg: "请求加好友",
|
||||
type: 4,
|
||||
});
|
||||
if(result.code ===0){
|
||||
ElMessage.success("请求发送成功");
|
||||
}else{
|
||||
ElMessage.error("请求发送失败,请检查是否已经发送过请求或者对方已经是好友");
|
||||
}
|
||||
}catch(e){
|
||||
console.log(e);
|
||||
}
|
||||
},
|
||||
//获取好友列表
|
||||
async displayFriends(){
|
||||
let result ={}
|
||||
try{
|
||||
result = await getFriendListService(this.tokenData);
|
||||
if(result.code ===0){
|
||||
this.FriendsGList = result.data.friends;
|
||||
this.GroupList=result.data.groups;
|
||||
this.FriendsTableIsDisplay = true;
|
||||
}else{
|
||||
ElMessage.error("获取好友列表失败");
|
||||
}
|
||||
}catch(e){
|
||||
console.log(e);
|
||||
}
|
||||
},
|
||||
//删除好友
|
||||
async DelFriendsOrGroup(index){
|
||||
// 删除前确认
|
||||
if (!confirm("确定删除吗?")) {
|
||||
return;
|
||||
}
|
||||
var id = this.FriendsGList[index].id;
|
||||
var name = this.FriendsGList[index].name;
|
||||
let result ={}
|
||||
try{
|
||||
result =await DelFGService({
|
||||
token: localStorage.getItem("token"),
|
||||
from_user_id: localStorage.getItem("userId"),
|
||||
to_user_id: id,
|
||||
msg: "删除好友",
|
||||
type: 1,
|
||||
});
|
||||
if(result.code ===0){
|
||||
ElMessage.success("删除好友成功");
|
||||
this.displayFriends();
|
||||
}else{
|
||||
ElMessage.error("删除好友失败");
|
||||
}
|
||||
}catch(e){
|
||||
console.log(e);
|
||||
}
|
||||
},
|
||||
async addGroupRequest(index){
|
||||
var group_id=this.groups[index].ID;
|
||||
let result={}
|
||||
let req={
|
||||
token: localStorage.getItem("token"),
|
||||
from_user_id: localStorage.getItem("userId"),
|
||||
to_user_id: 0,
|
||||
group_id: group_id,
|
||||
msg: "请求加入群组",
|
||||
type: 5,
|
||||
}
|
||||
try{
|
||||
|
||||
result = await addGroupRequestService(req);
|
||||
console.log(result.code);
|
||||
if(result.code === 0){
|
||||
ElMessage.success("请求发送成功");
|
||||
}else{
|
||||
ElMessage.error("操作失败已有请求或者已经是群组成员");
|
||||
}
|
||||
|
||||
}catch(e){
|
||||
ElMessage.error("操作失败已有请求或者已经是群组成员");
|
||||
}
|
||||
|
||||
|
||||
},
|
||||
|
||||
//接受好友请求
|
||||
async AcceptFriendsOrGroup(index){
|
||||
var id = this.FriendsGRequestList[index].id;
|
||||
var im_id = this.FriendsGRequestList[index].im_id;
|
||||
var name = this.FriendsGRequestList[index].name;
|
||||
let result ={}
|
||||
try{
|
||||
result =await acceptInviteService({
|
||||
token: localStorage.getItem("token"),
|
||||
id: im_id,
|
||||
from_user_id: localStorage.getItem("userId"),
|
||||
to_user_id: id,
|
||||
msg: "接受好友请求",
|
||||
index: 1,
|
||||
type: 1,
|
||||
});
|
||||
if(result.code ===0){
|
||||
ElMessage.success("接受好友请求成功");
|
||||
this.displayFriendReq()
|
||||
}else{
|
||||
ElMessage.error("接受好友请求失败");
|
||||
}
|
||||
}catch(e){
|
||||
console.log(e);
|
||||
}
|
||||
},
|
||||
handleAvatarFileUpload(e) {
|
||||
this.avatar_file = e.target.files[0];
|
||||
//判断文件类型是否为图片
|
||||
if (!this.avatar_file.type.startsWith("image/")) {
|
||||
ElMessage.error("请选择图片文件");
|
||||
this.avatar_file = null;
|
||||
return;
|
||||
}
|
||||
//this.UserUpdateForm.avatar = URL.createObjectURL(this.avatar_file);
|
||||
this.uploadAvatarFile();
|
||||
},
|
||||
readFileAndCalculateMD5() {
|
||||
return new Promise((resolve, reject) => {
|
||||
const reader = new FileReader();
|
||||
reader.onload = (event) => {
|
||||
const wordArray = CryptoJS.lib.WordArray.create(event.target.result);
|
||||
const md5Hash = CryptoJS.MD5(wordArray);
|
||||
const md5Str = md5Hash.toString(CryptoJS.enc.Hex);
|
||||
//console.log("onload: " + md5Str);
|
||||
this.file_md5 = md5Str;
|
||||
resolve(md5Str);
|
||||
};
|
||||
reader.onerror = (error) => {
|
||||
reject(error);
|
||||
};
|
||||
reader.readAsArrayBuffer(this.avatar_file);
|
||||
});
|
||||
},
|
||||
async uploadAvatarFile(){
|
||||
if (this.avatar_file == null) {
|
||||
alert('请先选择要上传的文件');
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
let result={};
|
||||
this.file_md5 = await this.readFileAndCalculateMD5(this.avatar_file);
|
||||
//console.log("md5:",this.file_md5);
|
||||
let md5_result = await GetFileInfoByMd5Service({"md5":this.file_md5,token:this.tokenData.token,"type":1});
|
||||
if(md5_result.code === 0){
|
||||
result = md5_result;
|
||||
}else{
|
||||
let formData = new FormData();
|
||||
formData.append('file', this.avatar_file);
|
||||
//console.log("add file: " + this.file);
|
||||
formData.append('upload_type', "1");
|
||||
formData.append('md5', this.file_md5);
|
||||
formData.append('auth_type', "public");
|
||||
//console.log("formData:",formData);
|
||||
|
||||
|
||||
result = await UploadFileService(formData,this.tokenData.token);
|
||||
if (result.code!== 0) {
|
||||
ElMessage.error('上传文件失败,请稍后再试');
|
||||
return;
|
||||
}
|
||||
}
|
||||
let resp_data = result.data;
|
||||
|
||||
//console.log("resp:",resp_data);
|
||||
let url = "https://tx.ljsea.top/tool/file/"+resp_data.FileStoreName;
|
||||
|
||||
this.UserUpdateForm.avatar = url;
|
||||
//更新用户信息
|
||||
await this.updateUserInfo();
|
||||
} catch (error) {
|
||||
ElMessage.error('上传文件时出现网络错误,请稍后再试');
|
||||
console.error(error);
|
||||
}
|
||||
},
|
||||
async updateUserInfo(){
|
||||
let result ={}
|
||||
try{
|
||||
let req={};
|
||||
req.token=localStorage.getItem("token");
|
||||
for(var key in this.UserUpdateForm){
|
||||
req[key] = this.UserUpdateForm[key];
|
||||
}
|
||||
result = await updateUserInfoService(req)
|
||||
if (result.code === 0) {
|
||||
ElMessage.success("更新成功");
|
||||
this.updateDialogVisible = false;
|
||||
} else {
|
||||
ElMessage.error("更新失败");
|
||||
}
|
||||
|
||||
}catch(e){
|
||||
console.log(e);
|
||||
}
|
||||
},
|
||||
async RefuseFriendsOrGroup(index){
|
||||
var id = this.FriendsGRequestList[index].id;
|
||||
var im_id = this.FriendsGRequestList[index].im_id;
|
||||
var name = this.FriendsGRequestList[index].name;
|
||||
let result ={}
|
||||
try{
|
||||
result =await rejectInviteService({
|
||||
token: localStorage.getItem("token"),
|
||||
id: im_id,
|
||||
from_user_id: localStorage.getItem("userId"),
|
||||
to_user_id: id,
|
||||
msg: "拒绝好友请求",
|
||||
index: 1,
|
||||
type: 1,
|
||||
});
|
||||
if(result.code ===0){
|
||||
ElMessage.success("拒绝请求成功");
|
||||
this.displayFriendReq()
|
||||
}else{
|
||||
ElMessage.error("拒绝请求失败");
|
||||
}
|
||||
}catch(e){
|
||||
console.log(e);
|
||||
}
|
||||
},
|
||||
|
||||
//获取好友请求列表
|
||||
async displayFriendReq(){
|
||||
let result ={}
|
||||
try{
|
||||
result =await getFriendReqService(this.tokenData)
|
||||
if(result.code ===0){
|
||||
this.FriendsGRequestList = result.data;
|
||||
this.FriendsRequestIsDisplay = true;
|
||||
}else{
|
||||
ElMessage.error("获取好友请求列表失败");
|
||||
}
|
||||
}catch(e){
|
||||
console.log(e);
|
||||
}
|
||||
|
||||
},
|
||||
onSubmit() {
|
||||
getUserList({ token: token });
|
||||
|
|
@ -47,23 +346,78 @@ export default {
|
|||
handleCurrentChange() {
|
||||
alert("页码发生变化" + val);
|
||||
},
|
||||
startChat(index){
|
||||
|
||||
//设置设备重启
|
||||
async startChat(index) {
|
||||
var id = this.tableData[index].ID;
|
||||
var name = this.tableData[index].Name;
|
||||
// var user_data = {
|
||||
// to_user_id: id,
|
||||
// to_user_name: this.tableData[index].Name,
|
||||
// };
|
||||
//转到聊天页面
|
||||
if(id == localStorage.getItem("userId")){
|
||||
alert("不能和自己聊天");
|
||||
return;
|
||||
}
|
||||
localStorage.setItem("to_user_id", id);
|
||||
localStorage.setItem("to_user_name", name);
|
||||
localStorage.setItem("to_user_id", this.tableData[index].ID);
|
||||
localStorage.setItem("to_user_name", this.tableData[index].Name);
|
||||
router.push("/im");
|
||||
|
||||
},
|
||||
async getMyUserInfo(id){
|
||||
let result = {};
|
||||
try{
|
||||
//获取用户信息
|
||||
this.tokenData.id = id;
|
||||
if(this.tokenData.id === undefined){
|
||||
this.tokenData.id = localStorage.getItem("userId");
|
||||
}
|
||||
result = await GetUserInfoService(this.tokenData)
|
||||
if(result.code ===0){
|
||||
this.UserUpdateForm.id = result.data.ID;
|
||||
this.UserUpdateForm.name = result.data.Name;
|
||||
this.UserUpdateForm.email = result.data.Email;
|
||||
this.UserUpdateForm.redis = result.data.Redis;
|
||||
this.UserUpdateForm.run = result.data.Run;
|
||||
this.UserUpdateForm.upload = result.data.Upload;
|
||||
this.UserUpdateForm.age = result.data.Age;
|
||||
this.UserUpdateForm.avatar = result.data.Avatar === "" ? "https://gep.ljsea.top/tool/file/9f29cc99-1054-4aff-ab37-e7c0016dd1b5.jpeg":result.data.Avatar;
|
||||
this.UserUpdateForm.role = result.data.Role;
|
||||
this.UserUpdateForm.gender = result.data.Gender;
|
||||
this.UserUpdateForm.create_time = result.data.CreatedAt;
|
||||
this.UserUpdateForm.update_time = result.data.UpdatedAt;
|
||||
this.UserUpdateForm.video_func = result.data.VideoFunc;
|
||||
this.UserUpdateForm.device_func = result.data.DeviceFunc;
|
||||
this.UserUpdateForm.cid_func = result.data.CIDFunc;
|
||||
//console.log("token data:",this.tokenData)
|
||||
if(result.data.ID === parseInt(this.tokenData.userId)){
|
||||
this.role = result.data.Role;
|
||||
localStorage.setItem("video_func", result["data"].VideoFunc > 0 ? "true" : "false");
|
||||
localStorage.setItem("device_func", result["data"].DeviceFunc > 0 ? "true" : "false");
|
||||
localStorage.setItem("cid_func", result["data"].CIDFunc > 0 ? "true" : "false");
|
||||
localStorage.setItem("avatar",result.data.Avatar);
|
||||
//console.log("my role:",this.role);
|
||||
}
|
||||
}
|
||||
}catch(e){
|
||||
console.log(e);
|
||||
}
|
||||
},
|
||||
|
||||
async displayMyInfo() {
|
||||
await this.getMyUserInfo(this.tokenData.user_id)
|
||||
this.updateDialogVisible= true;
|
||||
},
|
||||
async displayRedisInfo(){
|
||||
let result ={}
|
||||
let req={
|
||||
token: localStorage.getItem("token"),
|
||||
option: "all",
|
||||
}
|
||||
try{
|
||||
result = await GetRedisInfoService(req)
|
||||
if(result.code ===0){
|
||||
this.RedisList = result.data;
|
||||
this.RedisIsDisplay = true;
|
||||
}else{
|
||||
ElMessage.error("获取Redis数据失败");
|
||||
}
|
||||
}catch(e){
|
||||
console.log(e);
|
||||
}
|
||||
},
|
||||
async displayUserInfo(id) {
|
||||
await this.getMyUserInfo(id)
|
||||
this.updateDialogVisible= true;
|
||||
},
|
||||
|
||||
handleMenuSelect(val) {
|
||||
|
|
@ -87,10 +441,11 @@ export default {
|
|||
// 生命周期钩子会在组件生命周期的各个不同阶段被调用
|
||||
// 例如这个函数就会在组件挂载完成后被调用
|
||||
async mounted() {
|
||||
let now = new Date();
|
||||
if (localStorage.getItem("token") === null) {
|
||||
router.push("/login");
|
||||
}
|
||||
await this.getMyUserInfo(localStorage.getItem("userId"));
|
||||
|
||||
this.search_id = Cookies.get("search_id")?Cookies.get("search_id"):2002;
|
||||
this.keyword = Cookies.get("keyword")?Cookies.get("keyword"):"";
|
||||
},
|
||||
|
|
@ -99,58 +454,147 @@ export default {
|
|||
|
||||
<template>
|
||||
<div>
|
||||
<el-button
|
||||
type="primary"
|
||||
size="mini"
|
||||
@click.prevent="handleMenuSelect('/videoList')"
|
||||
>视频列表</el-button
|
||||
>
|
||||
<el-button
|
||||
type="primary"
|
||||
size="mini"
|
||||
@click.prevent="handleMenuSelect('/device')"
|
||||
>设备管理</el-button
|
||||
>
|
||||
<el-button
|
||||
type="primary"
|
||||
size="mini"
|
||||
@click.prevent="handleMenuSelect('/User')"
|
||||
>用户</el-button
|
||||
>
|
||||
<el-button
|
||||
type="primary"
|
||||
size="mini"
|
||||
@click.prevent="handleMenuSelect('/cid')"
|
||||
>集成部署</el-button
|
||||
>
|
||||
<Menu></Menu>
|
||||
<el-container style="height: 700px; border: 1px solid #eee">
|
||||
<el-header style="font-size: 40px; background-color: rgb(238, 241, 246)"
|
||||
>用户搜索列表</el-header
|
||||
>
|
||||
<el-container>
|
||||
<el-main>
|
||||
<el-form :inline="true" :model="tokenData" class="demo-form-inline">
|
||||
<el-col :span="8">
|
||||
<!-- 搜索与添加区域 -->
|
||||
<el-input
|
||||
placeholder="请输入ID"
|
||||
placeholder="请输入ID或关键字"
|
||||
v-model="search_id"
|
||||
clearable
|
||||
@clear="getUserList"
|
||||
>
|
||||
</el-input>
|
||||
<el-input
|
||||
placeholder="请输入关键字"
|
||||
v-model="keyword"
|
||||
clearable
|
||||
@clear="getUserList"
|
||||
>
|
||||
</el-input>
|
||||
<template #append>
|
||||
<el-button @click="getUserList"
|
||||
><el-icon><search /></el-icon
|
||||
></el-button>
|
||||
</template>
|
||||
</el-col>
|
||||
<el-form-item>
|
||||
<el-button type="primary" @click="displayFriends()"
|
||||
>好友列表</el-button
|
||||
>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button type="primary" @click="displayFriendReq()"
|
||||
>好友请求</el-button
|
||||
>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button type="primary" @click="displayMyInfo()"
|
||||
>我的信息</el-button
|
||||
>
|
||||
</el-form-item>
|
||||
<el-form-item v-if = "role === 'admin'">
|
||||
<el-button type="primary" @click="displayRedisInfo()"
|
||||
>Redis</el-button
|
||||
>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-dialog
|
||||
v-model="updateDialogVisible"
|
||||
title="我的信息"
|
||||
width="60%"
|
||||
:before-close="handleClose"
|
||||
>
|
||||
<!-- 内容主体区域 -->
|
||||
<el-form
|
||||
ref="updateFormRef"
|
||||
:model="UserUpdateForm"
|
||||
:rules="UserUpdateFormRules"
|
||||
label-width="70px"
|
||||
>
|
||||
<el-form-item label="ID" prop="id">
|
||||
<el-input
|
||||
disabled
|
||||
v-model="UserUpdateForm.id"
|
||||
autocomplete="on"
|
||||
></el-input>
|
||||
</el-form-item>
|
||||
<el-row>
|
||||
<el-form-item label="头像" prop="name">
|
||||
<el-avatar :size="80" :src="UserUpdateForm.avatar"></el-avatar>
|
||||
<!-- 选择图片 -->
|
||||
<input type="file" @change="handleAvatarFileUpload"/>
|
||||
</el-form-item>
|
||||
</el-row>
|
||||
<el-form-item label="用户名" prop="name">
|
||||
<el-input
|
||||
v-model="UserUpdateForm.name"
|
||||
autocomplete="on"
|
||||
></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="邮箱" prop="email">
|
||||
<el-input v-model="UserUpdateForm.email" disabled></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="Age" prop="age">
|
||||
<el-input v-model="UserUpdateForm.age"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="性别" prop="gender">
|
||||
<el-input v-model="UserUpdateForm.gender"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="运行权限" prop="run">
|
||||
<el-switch v-model="UserUpdateForm.run" :active-value="1" :inactive-value="-1" v-if="role === 'admin'"></el-switch>
|
||||
</el-form-item>
|
||||
<el-form-item label="redis权限" prop="redis">
|
||||
<el-switch v-model="UserUpdateForm.redis" :active-value="1" :inactive-value="-1" v-if="role === 'admin'"></el-switch>
|
||||
</el-form-item>
|
||||
<el-form-item label="上传权限" prop="upload">
|
||||
<el-switch v-model="UserUpdateForm.upload" :active-value="1" :inactive-value="-1" v-if="role === 'admin'"></el-switch>
|
||||
</el-form-item>
|
||||
<el-form-item label="用户权限" prop="role">
|
||||
<!-- <el-input v-model="UserUpdateForm.role" v-if="role === 'admin'"></el-input> -->
|
||||
<el-input v-model="UserUpdateForm.role" disabled v-if="role !== 'admin'"></el-input>
|
||||
|
||||
|
||||
<el-select v-model="UserUpdateForm.role" v-if="role === 'admin'">
|
||||
<el-option label="admin" value="admin">管理员</el-option>
|
||||
<el-option label="user" value="user">普通用户</el-option>
|
||||
</el-select>
|
||||
<!-- <el-selector v-model="UserUpdateForm.role" disabled v-if="role !== 'admin'">
|
||||
<el-option label="admin" value="admin"></el-option>
|
||||
<el-option label="user" value="user"></el-option>
|
||||
</el-selector> -->
|
||||
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="视频管理" prop="video_func">
|
||||
<el-switch v-model="UserUpdateForm.video_func" :active-value="1" :inactive-value="-1" v-if="role === 'admin'"></el-switch>
|
||||
</el-form-item>
|
||||
<el-form-item label="设备管理" prop="device_func">
|
||||
<el-switch v-model="UserUpdateForm.device_func" :active-value="1" :inactive-value="-1" v-if="role === 'admin'"></el-switch>
|
||||
</el-form-item>
|
||||
<el-form-item label="集成部署" prop="cid_func">
|
||||
<el-switch v-model="UserUpdateForm.cid_func" :active-value="1" :inactive-value="-1" v-if="role === 'admin'"></el-switch>
|
||||
</el-form-item>
|
||||
<el-form-item label="注册时间" prop="create_time">
|
||||
<el-input v-model="UserUpdateForm.create_time" disabled></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="上次修改" prop="update_time">
|
||||
<el-input v-model="UserUpdateForm.update_time" disabled></el-input>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<!-- 底部区域 -->
|
||||
<template #footer>
|
||||
<span class="dialog-footer">
|
||||
<el-button @click="updateDialogVisible = false"
|
||||
>取消</el-button
|
||||
>
|
||||
<el-button type="primary" @click="updateUserInfo()"
|
||||
>确定</el-button
|
||||
>
|
||||
</span>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</el-form-item>
|
||||
|
||||
<!-- 表单 -->
|
||||
<el-form :inline="true" :model="tokenData" class="demo-form-inline">
|
||||
<el-form-item>
|
||||
|
|
@ -162,6 +606,122 @@ export default {
|
|||
>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</el-form>
|
||||
|
||||
|
||||
|
||||
<el-dialog
|
||||
title="好友请求"
|
||||
width="50%"
|
||||
v-model="FriendsRequestIsDisplay"
|
||||
center>
|
||||
|
||||
<el-table :data="FriendsGRequestList" width="100%">
|
||||
<el-table-column prop="id" label="id" width="80"></el-table-column>
|
||||
<el-table-column
|
||||
prop="name"
|
||||
label="名称"
|
||||
width="100"
|
||||
></el-table-column>
|
||||
<el-table-column
|
||||
prop="email"
|
||||
label="用户邮箱"
|
||||
width="180"
|
||||
></el-table-column>
|
||||
<el-table-column
|
||||
prop="age"
|
||||
label="用户Age"
|
||||
width="120"
|
||||
></el-table-column>
|
||||
<el-table-column>
|
||||
<template #default="scope">
|
||||
<el-button
|
||||
type="primary"
|
||||
size="mini"
|
||||
@click.prevent="AcceptFriendsOrGroup(scope.$index)"
|
||||
>同意请求</el-button
|
||||
>
|
||||
<el-button
|
||||
type="primary"
|
||||
size="mini"
|
||||
@click.prevent="RefuseFriendsOrGroup(scope.$index)"
|
||||
>拒绝请求</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</el-dialog>
|
||||
|
||||
<el-dialog
|
||||
title="用户好友"
|
||||
width="40%"
|
||||
v-model="FriendsTableIsDisplay"
|
||||
center>
|
||||
|
||||
<el-table :data="FriendsGList" width="100%">
|
||||
<el-table-column prop="id" label="id" width="80"></el-table-column>
|
||||
<el-table-column
|
||||
prop="name"
|
||||
label="名称"
|
||||
width="100"
|
||||
></el-table-column>
|
||||
<el-table-column
|
||||
prop="email"
|
||||
label="用户邮箱"
|
||||
width="180"
|
||||
></el-table-column>
|
||||
<el-table-column>
|
||||
<template #default="scope">
|
||||
<el-button
|
||||
type="primary"
|
||||
size="mini"
|
||||
@click.prevent="DelFriendsOrGroup(scope.$index)"
|
||||
>删除好友或群组</el-button
|
||||
>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</el-dialog>
|
||||
|
||||
<el-dialog
|
||||
title="Redis数据"
|
||||
width="60%"
|
||||
v-model="RedisIsDisplay"
|
||||
center>
|
||||
|
||||
<el-table :data="RedisList" width="100%">
|
||||
<el-table-column
|
||||
prop="Key"
|
||||
label="Key"
|
||||
width="120"
|
||||
></el-table-column>
|
||||
<el-table-column
|
||||
prop="Value"
|
||||
label="Value"
|
||||
width="480"
|
||||
></el-table-column>
|
||||
<el-table-column
|
||||
prop="Type"
|
||||
label="Type"
|
||||
width="100"
|
||||
></el-table-column>
|
||||
<el-table-column
|
||||
prop="Expire"
|
||||
label="Expire(s)"
|
||||
width="100"
|
||||
></el-table-column>
|
||||
<el-table-column>
|
||||
<template #default="scope">
|
||||
<el-button
|
||||
type="primary"
|
||||
size="mini"
|
||||
@click.prevent="DelFriendsOrGroup(scope.$index)"
|
||||
>删除</el-button
|
||||
>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</el-dialog>
|
||||
|
||||
|
||||
<!-- 表格 :row-style="this.tableRowClassName"-->
|
||||
<el-table :data="tableData" width="100%" border>
|
||||
|
|
@ -185,9 +745,9 @@ export default {
|
|||
<el-table-column
|
||||
prop="Gender"
|
||||
label="用户性别"
|
||||
width="80"
|
||||
width="100"
|
||||
></el-table-column>
|
||||
<el-table-column label="操作" width="300">
|
||||
<el-table-column label="操作" width="400">
|
||||
<template #default="scope">
|
||||
<el-button
|
||||
type="primary"
|
||||
|
|
@ -195,6 +755,70 @@ export default {
|
|||
@click.prevent="startChat(scope.$index)"
|
||||
>聊天</el-button
|
||||
>
|
||||
<el-button
|
||||
type="primary"
|
||||
size="mini"
|
||||
@click.prevent="requestFriend(scope.$index)"
|
||||
>请求加好友</el-button
|
||||
>
|
||||
<!-- 如果有权限可设置用户权限 -->
|
||||
<v-if v-if="role === 'admin'">
|
||||
<el-button
|
||||
type="primary"
|
||||
size="mini"
|
||||
@click.prevent="setUserPermission(scope.$index)"
|
||||
>设置权限</el-button
|
||||
>
|
||||
</v-if>
|
||||
|
||||
|
||||
<!-- <el-button type="danger" size="mini">删除</el-button> -->
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
|
||||
<br />
|
||||
<h>
|
||||
群组列表
|
||||
</h>
|
||||
|
||||
<!-- 表格 :row-style="this.tableRowClassName"-->
|
||||
<el-table :data="groups" width="100%" border>
|
||||
:row-style="this.tableRowClassName"
|
||||
<el-table-column prop="ID" label="id" width="80"></el-table-column>
|
||||
<el-table-column
|
||||
prop="GroupName"
|
||||
label="名称"
|
||||
width="100"
|
||||
></el-table-column>
|
||||
<el-table-column
|
||||
prop="GroupInfo"
|
||||
label="描述"
|
||||
width="180"
|
||||
></el-table-column>
|
||||
<el-table-column
|
||||
prop="GroupType"
|
||||
label="类型"
|
||||
width="120"
|
||||
></el-table-column>
|
||||
<el-table-column
|
||||
prop="CreatedAt"
|
||||
label="创建时间"
|
||||
width="120"
|
||||
></el-table-column>
|
||||
<el-table-column
|
||||
prop="UpdatedAt"
|
||||
label="更新时间"
|
||||
width="120"
|
||||
></el-table-column>
|
||||
<el-table-column label="操作" width="350">
|
||||
<template #default="scope">
|
||||
<el-button
|
||||
type="primary"
|
||||
size="mini"
|
||||
@click.prevent="addGroupRequest(scope.$index)"
|
||||
>请求加入</el-button
|
||||
>
|
||||
<!-- <el-button type="danger" size="mini">删除</el-button> -->
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
|
|
|||
|
|
@ -18,6 +18,7 @@ const videoPlayer = ref(null);
|
|||
const myPlayer = ref(null);
|
||||
const route = useRoute();
|
||||
const router = useRouter();
|
||||
console.log("video player")
|
||||
if(localStorage.getItem('token')===null) {
|
||||
router.push("/login");
|
||||
}
|
||||
|
|
@ -60,8 +61,8 @@ onUnmounted(() => {
|
|||
</script>
|
||||
<style lang="scss" scoped>
|
||||
.video_wrap {
|
||||
width: 100vw;
|
||||
height: 100vh;
|
||||
width: 50vw;
|
||||
height: 60vh;
|
||||
position: relative;
|
||||
|
||||
.backIndex {
|
||||
|
|
|
|||
|
|
@ -1,17 +1,30 @@
|
|||
<script>
|
||||
import axios from "axios";
|
||||
import { getVideoListService, quashVideoService } from "@/api/video.js";
|
||||
import {
|
||||
getVideoListService,
|
||||
quashVideoService,
|
||||
deleteVideoService,
|
||||
} from "@/api/video.js";
|
||||
import { delayVideoService } from "@/api/video.js";
|
||||
import router from "@/router/index.js";
|
||||
import Cookies from "js-cookie";
|
||||
import { ElMessage } from "element-plus";
|
||||
import Menu from "@/views/Menu.vue";
|
||||
import VideoPlayer from "@/views/Video.vue";
|
||||
|
||||
export default {
|
||||
components: {
|
||||
VideoPlayer,
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
ip: "",
|
||||
tableData: [],
|
||||
file_sum_size: 0,
|
||||
dialogVisible: false,
|
||||
playing_video : "",
|
||||
tokenData: {
|
||||
id: -1,
|
||||
token: localStorage.getItem("token"),
|
||||
ip: localStorage.getItem("ip"),
|
||||
userId: localStorage.getItem("userId"),
|
||||
|
|
@ -47,7 +60,7 @@ export default {
|
|||
|
||||
for (let i = 0; i < len; i++) {
|
||||
//this.file_sum_size += parseFloat(data[i].file_size);
|
||||
data[i].file_size = parseFloat(data[i].file_size / 1024 / 1024).toFixed(
|
||||
data[i].FileSize = parseFloat(data[i].FileSize / 1024 / 1024).toFixed(
|
||||
2
|
||||
);
|
||||
}
|
||||
|
|
@ -66,10 +79,11 @@ export default {
|
|||
// 撤销操作
|
||||
let result = await quashVideoService(this.tokenData);
|
||||
if (result.code == 0) {
|
||||
alert(result.message);
|
||||
//alert(result.message);
|
||||
ElMessage.success("操作成功!");
|
||||
this.getVideoList();
|
||||
} else {
|
||||
alert("操作失败");
|
||||
ElMessage.error("操作失败!");
|
||||
}
|
||||
},
|
||||
onSubmit() {
|
||||
|
|
@ -82,12 +96,37 @@ export default {
|
|||
alert("页码发生变化" + val);
|
||||
},
|
||||
playVideo(index) {
|
||||
this.dialogVisible = true;
|
||||
// localStorage.setItem("is_to_play", "1");
|
||||
var id = this.tableData[index].ID;
|
||||
var name = this.tableData[index].VideoName;
|
||||
localStorage.setItem("video_id", id);
|
||||
localStorage.setItem("video_name", name);
|
||||
//alert("id=" + id + " name=" + name);
|
||||
router.push("/video");
|
||||
this.playing_video = "id: " + id + " ; name: " + name;
|
||||
components.updated();
|
||||
// //alert("id=" + id + " name=" + name);
|
||||
//router.push("/video");
|
||||
},
|
||||
async deleteVideo(index) {
|
||||
//判断是否删除
|
||||
if (!confirm("是否删除?")) {
|
||||
return;
|
||||
}
|
||||
var id = this.tableData[index].ID;
|
||||
let req = {
|
||||
id: id,
|
||||
userId: this.tokenData.userId,
|
||||
token: this.tokenData.token,
|
||||
type: "del_with_logic",
|
||||
};
|
||||
let result = await deleteVideoService(req);
|
||||
if (result.code == 0) {
|
||||
//alert(result.message);
|
||||
ElMessage.success("操作成功!");
|
||||
this.getVideoList();
|
||||
} else {
|
||||
ElMessage.error("操作失败!");
|
||||
}
|
||||
},
|
||||
async downloadVideo(index) {
|
||||
var id = this.tableData[index].ID;
|
||||
|
|
@ -133,6 +172,7 @@ export default {
|
|||
URL.revokeObjectURL(videoUrl);
|
||||
} catch (error) {
|
||||
console.error("下载视频时发生错误:", error);
|
||||
ElMessage.error("下载视频时发生错误");
|
||||
}
|
||||
},
|
||||
async delayVideo(index) {
|
||||
|
|
@ -149,9 +189,11 @@ export default {
|
|||
try {
|
||||
var d_re = await delayVideoService(delay_data);
|
||||
if (d_re.code == 0) {
|
||||
alert(d_re.message);
|
||||
//alert(d_re.message);
|
||||
ElMessage.success(d_re.message);
|
||||
} else {
|
||||
alert("操作失败");
|
||||
ElMessage.error("操作失败");
|
||||
//alert("操作失败");
|
||||
}
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
|
|
@ -211,12 +253,11 @@ export default {
|
|||
router.push("/login");
|
||||
}
|
||||
// console.log("mounted");
|
||||
await this.getIpClient();
|
||||
this.getIpClient();
|
||||
// if( Cookies.get("entrydate")){
|
||||
// console.log("entrydate:",Cookies.get("entrydate"));
|
||||
// this.tokenData.entrydate = [Object(Cookies.get("entrydate")[0]),Object(Cookies.get("entrydate")[1])];
|
||||
// }
|
||||
|
||||
this.getVideoList();
|
||||
},
|
||||
};
|
||||
|
|
@ -224,21 +265,7 @@ export default {
|
|||
|
||||
<template>
|
||||
<div>
|
||||
<el-button type="primary" size="mini" @click.prevent="handleMenuSelect('/videoList')"
|
||||
>视频列表</el-button
|
||||
>
|
||||
<el-button type="primary" size="mini" @click.prevent="handleMenuSelect('/device')"
|
||||
>设备管理</el-button
|
||||
>
|
||||
<el-button type="primary" size="mini" @click.prevent="handleMenuSelect('/User')"
|
||||
>用户</el-button
|
||||
>
|
||||
<el-button
|
||||
type="primary"
|
||||
size="mini"
|
||||
@click.prevent="handleMenuSelect('/cid')"
|
||||
>集成部署</el-button
|
||||
>
|
||||
<Menu></Menu>
|
||||
<el-container style="height: 700px; border: 1px solid #eee">
|
||||
<el-header style="font-size: 40px; background-color: rgb(238, 241, 246)"
|
||||
>监控视频列表</el-header
|
||||
|
|
@ -287,11 +314,15 @@ export default {
|
|||
</el-select>
|
||||
|
||||
<el-form-item>
|
||||
指定视频ID:
|
||||
<el-col :span="8">
|
||||
<el-input
|
||||
placeholder="指定视频ID"
|
||||
v-model="tokenData.id"
|
||||
></el-input>
|
||||
</el-col>
|
||||
<el-button type="primary" @click="getVideoList()">查询</el-button>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button type="primary" @click="logout()">退出登录</el-button>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button
|
||||
class="el-button--danger"
|
||||
|
|
@ -300,11 +331,6 @@ export default {
|
|||
>全部延迟删除</el-button
|
||||
>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button type="primary" @click="toDeviceM()"
|
||||
>设备信息</el-button
|
||||
>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button type="primary" @click="quashOption()"
|
||||
>撤销操作</el-button
|
||||
|
|
@ -315,6 +341,20 @@ export default {
|
|||
</el-form-item> -->
|
||||
</el-form>
|
||||
|
||||
|
||||
<el-dialog
|
||||
title="视频播放"
|
||||
v-model="dialogVisible"
|
||||
width="60%"
|
||||
height="60%"
|
||||
center
|
||||
>
|
||||
<div>
|
||||
视频播放({{playing_video }}):
|
||||
<VideoPlayer v-if="dialogVisible"></VideoPlayer>
|
||||
</div>
|
||||
</el-dialog>
|
||||
|
||||
<!-- 表格 :row-style="this.tableRowClassName"-->
|
||||
<el-table :data="tableData" width="100%" border>
|
||||
:row-style="this.tableRowClassName"
|
||||
|
|
@ -332,17 +372,17 @@ export default {
|
|||
<el-table-column
|
||||
prop="CreateTime"
|
||||
label="开始时间"
|
||||
width="180"
|
||||
width="160"
|
||||
></el-table-column>
|
||||
<el-table-column
|
||||
prop="EndTime"
|
||||
label="结束时间"
|
||||
width="180"
|
||||
width="160"
|
||||
></el-table-column>
|
||||
<el-table-column
|
||||
prop="DeleteTime"
|
||||
label="预期删除时间"
|
||||
width="180"
|
||||
width="160"
|
||||
></el-table-column>
|
||||
<el-table-column
|
||||
prop="FileSize"
|
||||
|
|
@ -354,7 +394,7 @@ export default {
|
|||
label="摄像头"
|
||||
width="50"
|
||||
></el-table-column>
|
||||
<el-table-column label="操作" width="300">
|
||||
<el-table-column label="操作" width="330">
|
||||
<template #default="scope">
|
||||
<el-button
|
||||
type="primary"
|
||||
|
|
@ -374,6 +414,12 @@ export default {
|
|||
@click.prevent="downloadVideo(scope.$index)"
|
||||
>下载</el-button
|
||||
>
|
||||
<el-button
|
||||
type="primary"
|
||||
size="mini"
|
||||
@click.prevent="deleteVideo(scope.$index)"
|
||||
>删除</el-button
|
||||
>
|
||||
|
||||
<!-- <el-button type="danger" size="mini">删除</el-button> -->
|
||||
</template>
|
||||
|
|
|
|||
|
|
@ -1,36 +1,113 @@
|
|||
<template>
|
||||
<div>
|
||||
<video ref="videoPlayer" class="video-js"></video>
|
||||
<div class="video_wrap">
|
||||
<video
|
||||
width="100%"
|
||||
height="100%"
|
||||
ref="videoPlayer"
|
||||
muted="muted"
|
||||
class="video-js video"
|
||||
></video>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import videojs from 'video.js';
|
||||
<script setup>
|
||||
import { onUnmounted, ref, nextTick } from "vue";
|
||||
import { useRoute, useRouter } from "vue-router";
|
||||
import videojs from "video.js";
|
||||
import "video.js/dist/video-js.css";
|
||||
|
||||
const videoPlayer = ref(null);
|
||||
const myPlayer = ref(null);
|
||||
|
||||
export default {
|
||||
name: 'VideoPlayer',
|
||||
props: {
|
||||
options: {
|
||||
type: Object,
|
||||
default() {
|
||||
return {};
|
||||
}
|
||||
}
|
||||
},
|
||||
name: "VideoPlayer",
|
||||
props: {},
|
||||
data() {
|
||||
return {
|
||||
player: null
|
||||
},
|
||||
methods: {
|
||||
playVideoA(){
|
||||
nextTick(() => {
|
||||
myPlayer.value = videojs(videoPlayer.value, {
|
||||
// poster: "//vjs.zencdn.net/v/oceans.png",//视频封面照片
|
||||
controls: true, //视频控件
|
||||
autoplay: true, //自动播放
|
||||
sources: [
|
||||
{
|
||||
src:
|
||||
"https://gep.ljsea.top/video/mp4?filename=" +
|
||||
localStorage.getItem("video_name") +
|
||||
"&id=" +
|
||||
localStorage.getItem("video_id") +
|
||||
"&ip=" +
|
||||
localStorage.getItem("ip")+
|
||||
"&userId=" +
|
||||
localStorage.getItem("userId") +
|
||||
"&token=" +
|
||||
localStorage.getItem("token"), //视频地址
|
||||
type: localStorage.getItem("video_name").split('.')[1]==="m3u8" ?"application/vnd.apple.mpegurl":"video/mp4",
|
||||
},
|
||||
],
|
||||
controlBar: {
|
||||
remainingTimeDisplay: {
|
||||
displayNegative: false,
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
this.player = videojs(this.$refs.videoPlayer, this.options, () => {
|
||||
this.player.log('onPlayerReady', this);
|
||||
playbackRates: [0.5, 1, 1.5, 2], //设置播放速度
|
||||
});
|
||||
});
|
||||
}
|
||||
},
|
||||
beforeDestroy() {
|
||||
if (this.player) {
|
||||
this.player.dispose();
|
||||
onMounted(){
|
||||
this.playVideoA();
|
||||
},
|
||||
onUnmounted(){
|
||||
if (myPlayer.value) {
|
||||
myPlayer.value.dispose();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// export default VideoPlayer;
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.video_wrap {
|
||||
width: "80%";
|
||||
height: "80%";
|
||||
position: relative;
|
||||
|
||||
.backIndex {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
height: 50px;
|
||||
width: 100%;
|
||||
line-height: 50px;
|
||||
background: rgba(0, 0, 0, 0.5);
|
||||
z-index: 99;
|
||||
padding-left: 10px;
|
||||
font-size: 20px;
|
||||
font-weight: 400;
|
||||
opacity: 0;
|
||||
transition: all 0.3s;
|
||||
color: white;
|
||||
|
||||
&:hover {
|
||||
opacity: 1;
|
||||
}
|
||||
span {
|
||||
cursor: pointer;
|
||||
}
|
||||
}
|
||||
|
||||
.video {
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
::v-deep(.vjs-big-play-button) {
|
||||
margin-left: 45%;
|
||||
margin-top: 20%;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
|
|
|||
|
|
@ -0,0 +1,104 @@
|
|||
<template>
|
||||
<div>
|
||||
<video ref="videoPlayer" autoplay playsinline></video>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import axios from "axios";
|
||||
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
videoPlayer: null,
|
||||
source: null, // 用于存储axios的CancelToken.source对象,以便后续取消请求
|
||||
};
|
||||
},
|
||||
mounted() {
|
||||
this.videoPlayer = this.$refs.videoPlayer;
|
||||
this.startVideoStream();
|
||||
},
|
||||
methods: {
|
||||
startVideoStream() {
|
||||
//let url = "https://gep.ljsea.top/device/video_feed?" +"&device_id=" +localStorage.getItem("realvp_device_id") +"&token=" +localStorage.getItem("token"); //视频地址
|
||||
|
||||
const deviceId = localStorage.getItem("realvp_device_id"); // 替换为实际存储设备id的方式和键名
|
||||
const token = localStorage.getItem("token"); // 替换为实际存储token的方式和键名
|
||||
const url = `https://gep.ljsea.top/device/video_feed?device_id=${deviceId}&token=${token}`;
|
||||
this.source = axios.CancelToken.source();
|
||||
axios
|
||||
.get(url, {
|
||||
responseType: "arraybuffer",
|
||||
cancelToken: this.source.token,
|
||||
})
|
||||
.then((response) => {
|
||||
console.log("获取视频流成功");
|
||||
const reader = response.data
|
||||
.pipeThrough(new window.TextDecoderStream())
|
||||
.getReader();
|
||||
const processData = () => {
|
||||
reader.read().then(({ done, value }) => {
|
||||
if (done) {
|
||||
return;
|
||||
}
|
||||
const dataString = new window.TextDecoder().decode(value);
|
||||
const parts = dataString.split("\r\n");
|
||||
|
||||
// 检查是否包含关键的视频流格式标识
|
||||
const hasFrameMarker = parts.some((part) =>
|
||||
part.startsWith("--frame")
|
||||
);
|
||||
const hasContentTypeMarker = parts.some(
|
||||
(part) => part === "Content-Type: image/jpeg"
|
||||
);
|
||||
if (!hasFrameMarker || !hasContentTypeMarker) {
|
||||
console.error("视频流数据格式不符合预期,无法解析");
|
||||
return;
|
||||
}
|
||||
|
||||
parts.forEach((part) => {
|
||||
if (part.startsWith("--frame")) {
|
||||
const imageData = [];
|
||||
let isImageData = false;
|
||||
parts.forEach((subPart) => {
|
||||
if (isImageData) {
|
||||
imageData.push(subPart);
|
||||
}
|
||||
if (subPart === "Content-Type: image/jpeg") {
|
||||
isImageData = true;
|
||||
}
|
||||
});
|
||||
const imageBlob = new Blob(imageData, { type: "image/jpeg" });
|
||||
const objectURL = URL.createObjectURL(imageBlob);
|
||||
this.videoPlayer.src = objectURL;
|
||||
}
|
||||
});
|
||||
processData();
|
||||
});
|
||||
};
|
||||
processData();
|
||||
})
|
||||
.catch((error) => {
|
||||
if (axios.isCancel(error)) {
|
||||
console.log("请求已取消");
|
||||
} else {
|
||||
console.error("获取视频流出错:", error);
|
||||
}
|
||||
});
|
||||
},
|
||||
},
|
||||
beforeUnmount() {
|
||||
if (this.source) {
|
||||
this.source.cancel("组件即将销毁,取消视频流请求");
|
||||
}
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
video {
|
||||
width: 100%;
|
||||
max-width: 800px;
|
||||
margin: 0 auto;
|
||||
}
|
||||
</style>
|
||||
|
|
@ -0,0 +1,76 @@
|
|||
<template>
|
||||
<div>
|
||||
<p>回调页面,加载授权信息中...</p>
|
||||
</div>
|
||||
</template>
|
||||
<script lang="ts" setup>
|
||||
//获取query参数
|
||||
import { useRouter, useRoute } from 'vue-router';
|
||||
import { onMounted } from 'vue';
|
||||
import { getTokenByCode } from '@/api/user.js';
|
||||
import { GetUserInfoService } from "@/api/user.js";
|
||||
import { ElMessage } from 'element-plus';
|
||||
const route = useRoute();
|
||||
|
||||
const router = useRouter();
|
||||
|
||||
interface UserToken {
|
||||
access_token: string; // 访问令牌
|
||||
refresh_token: string; // 刷新令牌
|
||||
user_id: number; // 用户ID
|
||||
username: string; // 用户名
|
||||
email: string; // 用户邮箱
|
||||
}
|
||||
|
||||
onMounted(async () => {
|
||||
// 获取query参数
|
||||
const queryParams = route.query;
|
||||
console.log('Received query parameters:', queryParams);
|
||||
let code = queryParams.code;
|
||||
//alert('Received code: ' + code);
|
||||
if (code) {
|
||||
let req = {
|
||||
code: code,
|
||||
};
|
||||
await getTokenByCode(req).then(async (res: any) => {
|
||||
if (res.code === 0) {
|
||||
ElMessage.success('获取Token成功');
|
||||
let userTokenInfo: UserToken = res.data;
|
||||
localStorage.setItem("token", userTokenInfo.access_token);
|
||||
localStorage.setItem("refresh_token", userTokenInfo.refresh_token);
|
||||
localStorage.setItem("userId", userTokenInfo.user_id.toString());
|
||||
localStorage.setItem("username", userTokenInfo.username);
|
||||
await getMyUserInfo(userTokenInfo.user_id);
|
||||
} else {
|
||||
console.error('获取Token失败:', res.message);
|
||||
ElMessage.error('获取Token失败: ' + res.message);
|
||||
}
|
||||
}).catch((error: any) => {
|
||||
console.error('请求错误:', error);
|
||||
});
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
const getMyUserInfo = async (id) => {
|
||||
let result = {};
|
||||
try {
|
||||
let tokenData = {
|
||||
token: localStorage.getItem("token"),
|
||||
id: id,
|
||||
};
|
||||
result = await GetUserInfoService(tokenData);
|
||||
//alert("get_user_info:" + JSON.stringify(result));
|
||||
if (result['code'] === 0) {
|
||||
//console.log("token data:",this.tokenData)
|
||||
localStorage.setItem("video_func", result["data"].VideoFunc > 0 ? "true" : "false");
|
||||
localStorage.setItem("device_func", result["data"].DeviceFunc > 0 ? "true" : "false");
|
||||
localStorage.setItem("cid_func", result["data"].CIDFunc > 0 ? "true" : "false");
|
||||
localStorage.setItem("role", result['data']['Role']);
|
||||
router.push("/user");
|
||||
}
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
|
@ -0,0 +1,126 @@
|
|||
<template>
|
||||
<div class="project-container">
|
||||
<h1 class="title">选择要跳转项目</h1>
|
||||
<div class="project-list">
|
||||
<el-card
|
||||
v-for="project in projects"
|
||||
:key="project.id"
|
||||
class="project-card"
|
||||
@click="handleSelect(project)"
|
||||
>
|
||||
<div class="card-content">
|
||||
<el-avatar :size="60" :src="project.avatar" />
|
||||
<div class="project-info">
|
||||
<h3>{{ project.name }}</h3>
|
||||
<p class="description">{{ project.description }}</p>
|
||||
</div>
|
||||
</div>
|
||||
</el-card>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { ref } from 'vue'
|
||||
import { useRouter } from 'vue-router'
|
||||
import {getUserTokenCode} from '@/api/user'
|
||||
import { ElMessage } from 'element-plus'
|
||||
|
||||
interface Project {
|
||||
id: string
|
||||
name: string
|
||||
description: string
|
||||
avatar: string
|
||||
path: string
|
||||
}
|
||||
|
||||
const router = useRouter()
|
||||
|
||||
// 模拟项目数据
|
||||
const projects = ref<Project[]>([
|
||||
{
|
||||
id: '1',
|
||||
name: 'SAW系统',
|
||||
description: '毕业设计及相关项目',
|
||||
avatar: 'https://www.ljsea.top/wp-content/uploads/2025/06/ljsea.jpg',
|
||||
path: 'https://sv.ljsea.top/#/callback' //path: 'https://gs.ljsea.top/callback'
|
||||
},
|
||||
])
|
||||
|
||||
const GetTokenCode =async () => {
|
||||
let req ={
|
||||
token: localStorage.getItem('token') || ''
|
||||
}
|
||||
await getUserTokenCode(req).then((res: any) => {
|
||||
if (res.code === 0) {
|
||||
if (res.data.code === '') {
|
||||
ElMessage.error('获取失败');
|
||||
return;
|
||||
}
|
||||
//alert('获取成功:'+res.data.code);
|
||||
localStorage.setItem('tokenCode', res.data.code);
|
||||
} else {
|
||||
console.error('获取Token失败:', res.message);
|
||||
}
|
||||
}).catch((error: any) => {
|
||||
console.error('请求错误:', error);
|
||||
});
|
||||
}
|
||||
|
||||
const handleSelect = async (project: Project) => {
|
||||
await GetTokenCode();
|
||||
let url = project.path + '?code=' + localStorage.getItem('tokenCode');
|
||||
window.open(url);
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.project-container {
|
||||
padding: 20px;
|
||||
max-width: 1200px;
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
.title {
|
||||
text-align: center;
|
||||
margin-bottom: 30px;
|
||||
color: #333;
|
||||
}
|
||||
|
||||
.project-list {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
|
||||
gap: 20px;
|
||||
}
|
||||
|
||||
.project-card {
|
||||
cursor: pointer;
|
||||
transition: transform 0.3s, box-shadow 0.3s;
|
||||
}
|
||||
|
||||
.project-card:hover {
|
||||
transform: translateY(-5px);
|
||||
box-shadow: 0 10px 20px rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
|
||||
.card-content {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: 15px;
|
||||
}
|
||||
|
||||
.project-info {
|
||||
margin-left: 15px;
|
||||
}
|
||||
|
||||
.project-info h3 {
|
||||
margin: 0 0 8px 0;
|
||||
color: #333;
|
||||
}
|
||||
|
||||
.description {
|
||||
margin: 0;
|
||||
color: #666;
|
||||
font-size: 14px;
|
||||
}
|
||||
</style>
|
||||
|
|
@ -0,0 +1,358 @@
|
|||
<template>
|
||||
<transition name="slide">
|
||||
<div class="side-panel">
|
||||
<button @click="handleClose" class="close-btn"></button>
|
||||
<el-button type="primary" @click="UpdateFileCOntent">保存修改</el-button>
|
||||
<div class="content">
|
||||
<h2>{{ fileName }}</h2>
|
||||
<div class="editor-container">
|
||||
<textarea
|
||||
ref="textareaRef"
|
||||
v-model="localContent"
|
||||
@input="handleInput"
|
||||
@scroll="handleScroll"
|
||||
spellcheck="false"
|
||||
></textarea>
|
||||
<pre class="highlight-container" ref="highlightRef"><code v-html="highlightedCode"></code></pre>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</transition>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref, watch, nextTick, onMounted } from "vue";
|
||||
import { updateConfigFileService } from "@/api/file";
|
||||
import { ElMessage } from "element-plus";
|
||||
import hljs from 'highlight.js';
|
||||
import 'highlight.js/styles/atom-one-dark.css';
|
||||
|
||||
const props = defineProps({
|
||||
content: {
|
||||
type: String,
|
||||
default: "",
|
||||
},
|
||||
show: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
fileName: {
|
||||
type: String,
|
||||
default: "编辑代码",
|
||||
},
|
||||
fileID: {
|
||||
type: Number,
|
||||
default: 0,
|
||||
},
|
||||
});
|
||||
|
||||
const emit = defineEmits<{
|
||||
(e: "close"): void;
|
||||
}>();
|
||||
|
||||
const textareaRef = ref<HTMLTextAreaElement | null>(null);
|
||||
const highlightRef = ref<HTMLElement | null>(null);
|
||||
const localContent = ref(props.content);
|
||||
const highlightedCode = ref('');
|
||||
|
||||
// 根据文件名判断语言
|
||||
const detectLanguage = (fileName: string) => {
|
||||
const extension = fileName.split('.').pop()?.toLowerCase();
|
||||
|
||||
const languageMap: Record<string, string> = {
|
||||
'js': 'javascript',
|
||||
'jsx': 'javascript',
|
||||
'ts': 'typescript',
|
||||
'tsx': 'typescript',
|
||||
'html': 'html',
|
||||
'css': 'css',
|
||||
'scss': 'scss',
|
||||
'less': 'less',
|
||||
'py': 'python',
|
||||
'java': 'java',
|
||||
'php': 'php',
|
||||
'go': 'go',
|
||||
'rb': 'ruby',
|
||||
'rs': 'rust',
|
||||
'c': 'c',
|
||||
'cpp': 'cpp',
|
||||
'cs': 'csharp',
|
||||
'json': 'json',
|
||||
'md': 'markdown',
|
||||
'xml': 'xml',
|
||||
'yaml': 'yaml',
|
||||
'yml': 'yaml',
|
||||
'sh': 'bash',
|
||||
'bash': 'bash',
|
||||
'sql': 'sql',
|
||||
};
|
||||
|
||||
return extension && languageMap[extension] ? languageMap[extension] : 'plaintext';
|
||||
};
|
||||
|
||||
// 高亮代码
|
||||
const highlightCode = () => {
|
||||
if (!localContent.value) {
|
||||
highlightedCode.value = '';
|
||||
return;
|
||||
}
|
||||
|
||||
const language = detectLanguage(props.fileName);
|
||||
|
||||
try {
|
||||
if (language !== 'plaintext') {
|
||||
const highlighted = hljs.highlight(localContent.value, { language });
|
||||
highlightedCode.value = highlighted.value;
|
||||
} else {
|
||||
// 如果无法检测语言,尝试自动检测
|
||||
const highlighted = hljs.highlightAuto(localContent.value);
|
||||
highlightedCode.value = highlighted.value;
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Highlight error:', error);
|
||||
// 降级处理:转义HTML并保留换行
|
||||
highlightedCode.value = localContent.value
|
||||
.replace(/&/g, '&')
|
||||
.replace(/</g, '<')
|
||||
.replace(/>/g, '>')
|
||||
.replace(/"/g, '"')
|
||||
.replace(/'/g, ''');
|
||||
}
|
||||
};
|
||||
|
||||
// 处理输入事件
|
||||
const handleInput = () => {
|
||||
highlightCode();
|
||||
nextTick(() => {
|
||||
if (textareaRef.value && highlightRef.value) {
|
||||
// 同步滚动位置
|
||||
highlightRef.value.scrollTop = textareaRef.value.scrollTop;
|
||||
highlightRef.value.scrollLeft = textareaRef.value.scrollLeft;
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
// 处理滚动事件
|
||||
const handleScroll = () => {
|
||||
if (textareaRef.value && highlightRef.value) {
|
||||
highlightRef.value.scrollTop = textareaRef.value.scrollTop;
|
||||
highlightRef.value.scrollLeft = textareaRef.value.scrollLeft;
|
||||
}
|
||||
};
|
||||
|
||||
// 当props.content变化时同步到本地
|
||||
watch(
|
||||
() => props.content,
|
||||
(newVal) => {
|
||||
localContent.value = newVal;
|
||||
highlightCode();
|
||||
}
|
||||
);
|
||||
|
||||
// 当面板显示时自动聚焦到textarea
|
||||
watch(
|
||||
() => props.show,
|
||||
async (newVal) => {
|
||||
if (newVal) {
|
||||
await nextTick();
|
||||
textareaRef.value?.focus();
|
||||
highlightCode();
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
// 初始化
|
||||
onMounted(() => {
|
||||
highlightCode();
|
||||
});
|
||||
|
||||
const handleClose = () => {
|
||||
emit("close");
|
||||
};
|
||||
|
||||
const UpdateFileCOntent = async () => {
|
||||
let req = {
|
||||
token: localStorage.getItem("token"),
|
||||
id: props.fileID,
|
||||
content: localContent.value,
|
||||
};
|
||||
try {
|
||||
let result = await updateConfigFileService(req);
|
||||
if (result["code"] === 0) {
|
||||
ElMessage.success("修改成功");
|
||||
} else {
|
||||
ElMessage.error("修改失败");
|
||||
}
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped lang="css">
|
||||
.side-panel {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
right: 0;
|
||||
width: 70%;
|
||||
height: 100%;
|
||||
background-color: #282c34;
|
||||
z-index: 1001;
|
||||
box-shadow: -2px 0 8px rgba(0, 0, 0, 0.3);
|
||||
padding: 20px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
color: #abb2bf;
|
||||
}
|
||||
|
||||
.close-btn {
|
||||
position: absolute;
|
||||
top: 10px;
|
||||
right: 10px;
|
||||
width: 30px;
|
||||
height: 30px;
|
||||
background: none;
|
||||
border: none;
|
||||
cursor: pointer;
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
.close-btn::before,
|
||||
.close-btn::after {
|
||||
content: '';
|
||||
position: absolute;
|
||||
width: 20px;
|
||||
height: 2px;
|
||||
background-color: #abb2bf;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
transition: background-color 0.2s;
|
||||
}
|
||||
|
||||
.close-btn::before {
|
||||
transform: translate(-50%, -50%) rotate(45deg);
|
||||
}
|
||||
|
||||
.close-btn::after {
|
||||
transform: translate(-50%, -50%) rotate(-45deg);
|
||||
}
|
||||
|
||||
.close-btn:hover::before,
|
||||
.close-btn:hover::after {
|
||||
background-color: #61afef;
|
||||
}
|
||||
|
||||
.content {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
margin-top: 20px;
|
||||
}
|
||||
|
||||
.content h2 {
|
||||
color: #e5e5e5;
|
||||
margin-bottom: 15px;
|
||||
}
|
||||
|
||||
.editor-container {
|
||||
position: relative;
|
||||
flex: 1;
|
||||
border-radius: 4px;
|
||||
background-color: #282c34;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.editor-container textarea {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
padding: 12px;
|
||||
border: 1px solid #3e4451;
|
||||
border-radius: 4px;
|
||||
resize: none;
|
||||
font-family: 'Consolas', 'Monaco', 'Courier New', monospace;
|
||||
font-size: 14px;
|
||||
line-height: 1.5;
|
||||
color: transparent;
|
||||
background-color: transparent;
|
||||
caret-color: #61afef;
|
||||
z-index: 2;
|
||||
white-space: pre;
|
||||
overflow: auto;
|
||||
tab-size: 2;
|
||||
}
|
||||
|
||||
.editor-container textarea:focus {
|
||||
outline: none;
|
||||
border-color: #61afef;
|
||||
}
|
||||
|
||||
.highlight-container {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
padding: 12px;
|
||||
margin: 0;
|
||||
font-family: 'Consolas', 'Monaco', 'Courier New', monospace;
|
||||
font-size: 14px;
|
||||
line-height: 1.5;
|
||||
pointer-events: none;
|
||||
overflow: auto;
|
||||
z-index: 1;
|
||||
white-space: pre;
|
||||
tab-size: 2;
|
||||
background-color: #282c34;
|
||||
}
|
||||
|
||||
.highlight-container code {
|
||||
font-family: inherit;
|
||||
}
|
||||
|
||||
/* 滚动条样式 */
|
||||
.editor-container textarea::-webkit-scrollbar,
|
||||
.highlight-container::-webkit-scrollbar {
|
||||
width: 8px;
|
||||
height: 8px;
|
||||
}
|
||||
|
||||
.editor-container textarea::-webkit-scrollbar-track,
|
||||
.highlight-container::-webkit-scrollbar-track {
|
||||
background: #21252b;
|
||||
}
|
||||
|
||||
.editor-container textarea::-webkit-scrollbar-thumb,
|
||||
.highlight-container::-webkit-scrollbar-thumb {
|
||||
background: #3e4451;
|
||||
border-radius: 4px;
|
||||
}
|
||||
|
||||
.editor-container textarea::-webkit-scrollbar-thumb:hover,
|
||||
.highlight-container::-webkit-scrollbar-thumb:hover {
|
||||
background: #4b5363;
|
||||
}
|
||||
|
||||
/* 保存按钮样式 */
|
||||
:deep(.el-button--primary) {
|
||||
background-color: #61afef;
|
||||
border-color: #61afef;
|
||||
}
|
||||
|
||||
:deep(.el-button--primary:hover) {
|
||||
background-color: #528bbc;
|
||||
border-color: #528bbc;
|
||||
}
|
||||
|
||||
.slide-enter-active,
|
||||
.slide-leave-active {
|
||||
transition: transform 0.3s ease;
|
||||
}
|
||||
|
||||
.slide-enter-from,
|
||||
.slide-leave-to {
|
||||
transform: translateX(100%);
|
||||
}
|
||||
</style>
|
||||
Loading…
Reference in New Issue