A:引入axios;增加初始化访问示例
This commit is contained in:
1 parent
e5e043246e
commit
1b35e2dfd7
14 files changed
+1352
-278
No files matched your search
@@ -1,3 +1,2 @@
|
||||
VITE_MODE='development'
|
||||
VITE_APP_API_URL='http://192.****:8008/api/'
|
||||
VITE_API_URL=http://localhost:3000/api
|
||||
VITE_APP_API_URL='http://localhost:8268/api'
|
||||
@@ -1,2 +1,2 @@
|
||||
VITE_MODE='production'
|
||||
VITE_APP_API_URL='http://xxx.xxx.xxx.xx:8008/api/'
|
||||
VITE_APP_API_URL='http://localhost:8268/api'
|
||||
@@ -15,6 +15,7 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"@vicons/ionicons5": "^0.13.0",
|
||||
"axios": "^1.10.0",
|
||||
"gsap": "^3.13.0",
|
||||
"pinia": "^3.0.1",
|
||||
"unplugin-auto-import": "^19.3.0",
|
||||
|
||||
Generated
+284
@@ -11,6 +11,9 @@ importers:
|
||||
'@vicons/ionicons5':
|
||||
specifier: ^0.13.0
|
||||
version: 0.13.0
|
||||
axios:
|
||||
specifier: ^1.10.0
|
||||
version: 1.10.0
|
||||
gsap:
|
||||
specifier: ^3.13.0
|
||||
version: 3.13.0
|
||||
@@ -20,6 +23,9 @@ importers:
|
||||
unplugin-auto-import:
|
||||
specifier: ^19.3.0
|
||||
version: 19.3.0
|
||||
unplugin-vue-components:
|
||||
specifier: ^28.7.0
|
||||
version: 28.7.0(@babel/parser@7.27.2)(vue@3.5.14(typescript@5.8.3))
|
||||
vue:
|
||||
specifier: ^3.5.13
|
||||
version: 3.5.14(typescript@5.8.3)
|
||||
@@ -971,6 +977,10 @@ packages:
|
||||
resolution: {integrity: sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==, tarball: https://registry.npmmirror.com/ansi-styles/-/ansi-styles-6.2.1.tgz}
|
||||
engines: {node: '>=12'}
|
||||
|
||||
anymatch@3.1.3:
|
||||
resolution: {integrity: sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==}
|
||||
engines: {node: '>= 8'}
|
||||
|
||||
argparse@2.0.1:
|
||||
resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==, tarball: https://registry.npmmirror.com/argparse/-/argparse-2.0.1.tgz}
|
||||
|
||||
@@ -981,9 +991,19 @@ packages:
|
||||
async-validator@4.2.5:
|
||||
resolution: {integrity: sha512-7HhHjtERjqlNbZtqNqy2rckN/SpOOlmDliet+lP7k+eKZEjPk3DgyeU9lIXLdeLz0uBbbVp+9Qdow9wJWgwwfg==}
|
||||
|
||||
asynckit@0.4.0:
|
||||
resolution: {integrity: sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==}
|
||||
|
||||
axios@1.10.0:
|
||||
resolution: {integrity: sha512-/1xYAC4MP/HEG+3duIhFr4ZQXR4sQXOIe+o6sdqzeykGLx6Upp/1p8MHqhINOvGeP7xyNHe7tsiJByc4SSVUxw==}
|
||||
|
||||
balanced-match@1.0.2:
|
||||
resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==, tarball: https://registry.npmmirror.com/balanced-match/-/balanced-match-1.0.2.tgz}
|
||||
|
||||
binary-extensions@2.3.0:
|
||||
resolution: {integrity: sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==}
|
||||
engines: {node: '>=8'}
|
||||
|
||||
birpc@2.3.0:
|
||||
resolution: {integrity: sha512-ijbtkn/F3Pvzb6jHypHRyve2QApOCZDR25D/VnkY2G/lBNcXCTsnsCxgY4k4PkVB7zfwzYbY3O9Lcqe3xufS5g==, tarball: https://registry.npmmirror.com/birpc/-/birpc-2.3.0.tgz}
|
||||
|
||||
@@ -1013,6 +1033,10 @@ packages:
|
||||
resolution: {integrity: sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ==, tarball: https://registry.npmmirror.com/cac/-/cac-6.7.14.tgz}
|
||||
engines: {node: '>=8'}
|
||||
|
||||
call-bind-apply-helpers@1.0.2:
|
||||
resolution: {integrity: sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==}
|
||||
engines: {node: '>= 0.4'}
|
||||
|
||||
callsites@3.1.0:
|
||||
resolution: {integrity: sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==, tarball: https://registry.npmmirror.com/callsites/-/callsites-3.1.0.tgz}
|
||||
engines: {node: '>=6'}
|
||||
@@ -1032,6 +1056,10 @@ packages:
|
||||
resolution: {integrity: sha512-OAlb+T7V4Op9OwdkjmguYRqncdlx5JiofwOAUkmTF+jNdHwzTaTs4sRAGpzLF3oOz5xAyDGrPgeIDFQmDOTiJw==, tarball: https://registry.npmmirror.com/check-error/-/check-error-2.1.1.tgz}
|
||||
engines: {node: '>= 16'}
|
||||
|
||||
chokidar@3.6.0:
|
||||
resolution: {integrity: sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==}
|
||||
engines: {node: '>= 8.10.0'}
|
||||
|
||||
color-convert@2.0.1:
|
||||
resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==, tarball: https://registry.npmmirror.com/color-convert/-/color-convert-2.0.1.tgz}
|
||||
engines: {node: '>=7.0.0'}
|
||||
@@ -1039,6 +1067,10 @@ packages:
|
||||
color-name@1.1.4:
|
||||
resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==, tarball: https://registry.npmmirror.com/color-name/-/color-name-1.1.4.tgz}
|
||||
|
||||
combined-stream@1.0.8:
|
||||
resolution: {integrity: sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==}
|
||||
engines: {node: '>= 0.8'}
|
||||
|
||||
commander@10.0.1:
|
||||
resolution: {integrity: sha512-y4Mg2tXshplEbSGzx7amzPwKKOCGuoSRP/CjEdwwk0FOGlUbq6lKuoyDZTNZkmxHdJtp54hdfY/JUrdL7Xfdug==, tarball: https://registry.npmmirror.com/commander/-/commander-10.0.1.tgz}
|
||||
engines: {node: '>=14'}
|
||||
@@ -1130,6 +1162,14 @@ packages:
|
||||
resolution: {integrity: sha512-N+MeXYoqr3pOgn8xfyRPREN7gHakLYjhsHhWGT3fWAiL4IkAt0iDw14QiiEm2bE30c5XX5q0FtAA3CK5f9/BUg==, tarball: https://registry.npmmirror.com/define-lazy-prop/-/define-lazy-prop-3.0.0.tgz}
|
||||
engines: {node: '>=12'}
|
||||
|
||||
delayed-stream@1.0.0:
|
||||
resolution: {integrity: sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==}
|
||||
engines: {node: '>=0.4.0'}
|
||||
|
||||
dunder-proto@1.0.1:
|
||||
resolution: {integrity: sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==}
|
||||
engines: {node: '>= 0.4'}
|
||||
|
||||
eastasianwidth@0.2.0:
|
||||
resolution: {integrity: sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==, tarball: https://registry.npmmirror.com/eastasianwidth/-/eastasianwidth-0.2.0.tgz}
|
||||
|
||||
@@ -1158,9 +1198,25 @@ packages:
|
||||
error-stack-parser-es@0.1.5:
|
||||
resolution: {integrity: sha512-xHku1X40RO+fO8yJ8Wh2f2rZWVjqyhb1zgq1yZ8aZRQkv6OOKhKWRUaht3eSCUbAOBaKIgM+ykwFLE+QUxgGeg==, tarball: https://registry.npmmirror.com/error-stack-parser-es/-/error-stack-parser-es-0.1.5.tgz}
|
||||
|
||||
es-define-property@1.0.1:
|
||||
resolution: {integrity: sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==}
|
||||
engines: {node: '>= 0.4'}
|
||||
|
||||
es-errors@1.3.0:
|
||||
resolution: {integrity: sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==}
|
||||
engines: {node: '>= 0.4'}
|
||||
|
||||
es-module-lexer@1.7.0:
|
||||
resolution: {integrity: sha512-jEQoCwk8hyb2AZziIOLhDqpm5+2ww5uIE6lkO/6jcOCusfk6LhMHpXXfBLXTZ7Ydyt0j4VoUQv6uGNYbdW+kBA==, tarball: https://registry.npmmirror.com/es-module-lexer/-/es-module-lexer-1.7.0.tgz}
|
||||
|
||||
es-object-atoms@1.1.1:
|
||||
resolution: {integrity: sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==}
|
||||
engines: {node: '>= 0.4'}
|
||||
|
||||
es-set-tostringtag@2.1.0:
|
||||
resolution: {integrity: sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==}
|
||||
engines: {node: '>= 0.4'}
|
||||
|
||||
esbuild@0.25.4:
|
||||
resolution: {integrity: sha512-8pgjLUcUjcgDg+2Q4NYXnPbo/vncAY4UmyaCm0jZevERqCHZIaWwdJHkf8XQtu4AxSKCdvrUbT0XUr1IdZzI8Q==, tarball: https://registry.npmmirror.com/esbuild/-/esbuild-0.25.4.tgz}
|
||||
engines: {node: '>=18'}
|
||||
@@ -1317,10 +1373,23 @@ packages:
|
||||
flatted@3.3.3:
|
||||
resolution: {integrity: sha512-GX+ysw4PBCz0PzosHDepZGANEuFCMLrnRTiEy9McGjmkCQYwRq4A/X786G/fjM/+OjsWSU1ZrY5qyARZmO/uwg==, tarball: https://registry.npmmirror.com/flatted/-/flatted-3.3.3.tgz}
|
||||
|
||||
follow-redirects@1.15.9:
|
||||
resolution: {integrity: sha512-gew4GsXizNgdoRyqmyfMHyAmXsZDk6mHkSxZFCzW9gwlbtOW44CDtYavM+y+72qD/Vq2l550kMF52DT8fOLJqQ==}
|
||||
engines: {node: '>=4.0'}
|
||||
peerDependencies:
|
||||
debug: '*'
|
||||
peerDependenciesMeta:
|
||||
debug:
|
||||
optional: true
|
||||
|
||||
foreground-child@3.3.1:
|
||||
resolution: {integrity: sha512-gIXjKqtFuWEgzFRJA9WCQeSJLZDjgJUOMCMzxtvFq/37KojM1BFGufqsCy0r4qSQmYLsZYMeyRqzIWOMup03sw==, tarball: https://registry.npmmirror.com/foreground-child/-/foreground-child-3.3.1.tgz}
|
||||
engines: {node: '>=14'}
|
||||
|
||||
form-data@4.0.3:
|
||||
resolution: {integrity: sha512-qsITQPfmvMOSAdeyZ+12I1c+CKSstAFAwu+97zrnWAbIr5u8wfsExUzCesVLC8NgHuRUqNN4Zy6UPWUTRGslcA==}
|
||||
engines: {node: '>= 6'}
|
||||
|
||||
fs-extra@11.3.0:
|
||||
resolution: {integrity: sha512-Z4XaCL6dUDHfP/jT25jJKMmtxvuwbkrD1vNSMFlo9lNLY2c5FHYSQgHPRZUjAB26TpDEoW9HCOgplrdbaPV/ew==, tarball: https://registry.npmmirror.com/fs-extra/-/fs-extra-11.3.0.tgz}
|
||||
engines: {node: '>=14.14'}
|
||||
@@ -1330,10 +1399,21 @@ packages:
|
||||
engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0}
|
||||
os: [darwin]
|
||||
|
||||
function-bind@1.1.2:
|
||||
resolution: {integrity: sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==}
|
||||
|
||||
gensync@1.0.0-beta.2:
|
||||
resolution: {integrity: sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==, tarball: https://registry.npmmirror.com/gensync/-/gensync-1.0.0-beta.2.tgz}
|
||||
engines: {node: '>=6.9.0'}
|
||||
|
||||
get-intrinsic@1.3.0:
|
||||
resolution: {integrity: sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==}
|
||||
engines: {node: '>= 0.4'}
|
||||
|
||||
get-proto@1.0.1:
|
||||
resolution: {integrity: sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==}
|
||||
engines: {node: '>= 0.4'}
|
||||
|
||||
get-stream@9.0.1:
|
||||
resolution: {integrity: sha512-kVCxPF3vQM/N0B1PmoqVUqgHP+EeVjmZSQn+1oCRPxd2P21P2F19lIgbR3HBosbB1PUhOAoctJnfEn2GbN2eZA==, tarball: https://registry.npmmirror.com/get-stream/-/get-stream-9.0.1.tgz}
|
||||
engines: {node: '>=18'}
|
||||
@@ -1358,6 +1438,10 @@ packages:
|
||||
resolution: {integrity: sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==, tarball: https://registry.npmmirror.com/globals/-/globals-14.0.0.tgz}
|
||||
engines: {node: '>=18'}
|
||||
|
||||
gopd@1.2.0:
|
||||
resolution: {integrity: sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==}
|
||||
engines: {node: '>= 0.4'}
|
||||
|
||||
graceful-fs@4.2.11:
|
||||
resolution: {integrity: sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==, tarball: https://registry.npmmirror.com/graceful-fs/-/graceful-fs-4.2.11.tgz}
|
||||
|
||||
@@ -1371,6 +1455,18 @@ packages:
|
||||
resolution: {integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==, tarball: https://registry.npmmirror.com/has-flag/-/has-flag-4.0.0.tgz}
|
||||
engines: {node: '>=8'}
|
||||
|
||||
has-symbols@1.1.0:
|
||||
resolution: {integrity: sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==}
|
||||
engines: {node: '>= 0.4'}
|
||||
|
||||
has-tostringtag@1.0.2:
|
||||
resolution: {integrity: sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==}
|
||||
engines: {node: '>= 0.4'}
|
||||
|
||||
hasown@2.0.2:
|
||||
resolution: {integrity: sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==}
|
||||
engines: {node: '>= 0.4'}
|
||||
|
||||
he@1.2.0:
|
||||
resolution: {integrity: sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==, tarball: https://registry.npmmirror.com/he/-/he-1.2.0.tgz}
|
||||
hasBin: true
|
||||
@@ -1421,6 +1517,10 @@ packages:
|
||||
ini@1.3.8:
|
||||
resolution: {integrity: sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==, tarball: https://registry.npmmirror.com/ini/-/ini-1.3.8.tgz}
|
||||
|
||||
is-binary-path@2.1.0:
|
||||
resolution: {integrity: sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==}
|
||||
engines: {node: '>=8'}
|
||||
|
||||
is-docker@3.0.0:
|
||||
resolution: {integrity: sha512-eljcgEDlEns/7AXFosB5K/2nCM4P7FQPkGc/DWLy5rmFEWvZayGrik1d9/QIY5nJ4f9YsVvBkA6kJpHn9rISdQ==, tarball: https://registry.npmmirror.com/is-docker/-/is-docker-3.0.0.tgz}
|
||||
engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0}
|
||||
@@ -1577,6 +1677,10 @@ packages:
|
||||
magic-string@0.30.17:
|
||||
resolution: {integrity: sha512-sNPKHvyjVf7gyjwS4xGTaW/mCnF8wnjtifKBEhxfZ7E/S8tQ0rssrwGNn6q8JH/ohItJfSQp9mBtQYuTlH5QnA==, tarball: https://registry.npmmirror.com/magic-string/-/magic-string-0.30.17.tgz}
|
||||
|
||||
math-intrinsics@1.1.0:
|
||||
resolution: {integrity: sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==}
|
||||
engines: {node: '>= 0.4'}
|
||||
|
||||
memorystream@0.3.1:
|
||||
resolution: {integrity: sha512-S3UwM3yj5mtUSEfP41UZmt/0SCoVYUcU1rkXv+BQ5Ig8ndL4sPoJNBUJERafdPb5jjHJGuMgytgKvKIf58XNBw==, tarball: https://registry.npmmirror.com/memorystream/-/memorystream-0.3.1.tgz}
|
||||
engines: {node: '>= 0.10.0'}
|
||||
@@ -1589,6 +1693,14 @@ packages:
|
||||
resolution: {integrity: sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==, tarball: https://registry.npmmirror.com/micromatch/-/micromatch-4.0.8.tgz}
|
||||
engines: {node: '>=8.6'}
|
||||
|
||||
mime-db@1.52.0:
|
||||
resolution: {integrity: sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==}
|
||||
engines: {node: '>= 0.6'}
|
||||
|
||||
mime-types@2.1.35:
|
||||
resolution: {integrity: sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==}
|
||||
engines: {node: '>= 0.6'}
|
||||
|
||||
minimatch@3.1.2:
|
||||
resolution: {integrity: sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==, tarball: https://registry.npmmirror.com/minimatch/-/minimatch-3.1.2.tgz}
|
||||
|
||||
@@ -1646,6 +1758,10 @@ packages:
|
||||
engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0}
|
||||
hasBin: true
|
||||
|
||||
normalize-path@3.0.0:
|
||||
resolution: {integrity: sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==}
|
||||
engines: {node: '>=0.10.0'}
|
||||
|
||||
npm-normalize-package-bin@4.0.0:
|
||||
resolution: {integrity: sha512-TZKxPvItzai9kN9H/TkmCtx/ZN/hvr3vUycjlfmH0ootY9yFBzNOpiXAdIn1Iteqsvk4lQn6B5PTrt+n6h8k/w==, tarball: https://registry.npmmirror.com/npm-normalize-package-bin/-/npm-normalize-package-bin-4.0.0.tgz}
|
||||
engines: {node: ^18.17.0 || >=20.5.0}
|
||||
@@ -1783,6 +1899,9 @@ packages:
|
||||
proto-list@1.2.4:
|
||||
resolution: {integrity: sha512-vtK/94akxsTMhe0/cbfpR+syPuszcuwhqVjJq26CuNDgFGj682oRBXOP5MJpv2r7JtE8MsiepGIqvvOTBwn2vA==, tarball: https://registry.npmmirror.com/proto-list/-/proto-list-1.2.4.tgz}
|
||||
|
||||
proxy-from-env@1.1.0:
|
||||
resolution: {integrity: sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==}
|
||||
|
||||
punycode@2.3.1:
|
||||
resolution: {integrity: sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==, tarball: https://registry.npmmirror.com/punycode/-/punycode-2.3.1.tgz}
|
||||
engines: {node: '>=6'}
|
||||
@@ -1797,6 +1916,10 @@ packages:
|
||||
resolution: {integrity: sha512-qpt8EwugBWDw2cgE2W+/3oxC+KTez2uSVR8JU9Q36TXPAGCaozfQUs59v4j4GFpWTaw0i6hAZSvOmu1J0uOEUg==, tarball: https://registry.npmmirror.com/read-package-json-fast/-/read-package-json-fast-4.0.0.tgz}
|
||||
engines: {node: ^18.17.0 || >=20.5.0}
|
||||
|
||||
readdirp@3.6.0:
|
||||
resolution: {integrity: sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==}
|
||||
engines: {node: '>=8.10.0'}
|
||||
|
||||
resolve-from@4.0.0:
|
||||
resolution: {integrity: sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==, tarball: https://registry.npmmirror.com/resolve-from/-/resolve-from-4.0.0.tgz}
|
||||
engines: {node: '>=4'}
|
||||
@@ -1934,6 +2057,10 @@ packages:
|
||||
resolution: {integrity: sha512-mEwzpUgrLySlveBwEVDMKk5B57bhLPYovRfPAXD5gA/98Opn0rCDj3GtLwFvCvH5RK9uPCExUROW5NjDwvqkxw==, tarball: https://registry.npmmirror.com/tinyglobby/-/tinyglobby-0.2.13.tgz}
|
||||
engines: {node: '>=12.0.0'}
|
||||
|
||||
tinyglobby@0.2.14:
|
||||
resolution: {integrity: sha512-tX5e7OM1HnYr2+a2C/4V0htOcSQcoSTH9KgJnVvNm5zm/cyEWKJ7j7YutsH9CxMdtOkkLFy2AHrMci9IM8IPZQ==}
|
||||
engines: {node: '>=12.0.0'}
|
||||
|
||||
tinypool@1.0.2:
|
||||
resolution: {integrity: sha512-al6n+QEANGFOMf/dmUMsuS5/r9B06uwlyNjZZql/zv8J7ybHCgoihBNORZCY2mzUuAnomQa2JdhyHKzZxPCrFA==, tarball: https://registry.npmmirror.com/tinypool/-/tinypool-1.0.2.tgz}
|
||||
engines: {node: ^18.0.0 || >=20.0.0}
|
||||
@@ -2028,6 +2155,19 @@ packages:
|
||||
resolution: {integrity: sha512-8U/MtpkPkkk3Atewj1+RcKIjb5WBimZ/WSLhhR3w6SsIj8XJuKTacSP8g+2JhfSGw0Cb125Y+2zA/IzJZDVbhA==}
|
||||
engines: {node: '>=18.12.0'}
|
||||
|
||||
unplugin-vue-components@28.7.0:
|
||||
resolution: {integrity: sha512-3SuWAHlTjOiZckqRBGXRdN/k6IMmKyt2Ch5/+DKwYaT321H0ItdZDvW4r8/YkEKQpN9TN3F/SZ0W342gQROC3Q==}
|
||||
engines: {node: '>=14'}
|
||||
peerDependencies:
|
||||
'@babel/parser': ^7.15.8
|
||||
'@nuxt/kit': ^3.2.2
|
||||
vue: 2 || 3
|
||||
peerDependenciesMeta:
|
||||
'@babel/parser':
|
||||
optional: true
|
||||
'@nuxt/kit':
|
||||
optional: true
|
||||
|
||||
unplugin@2.3.5:
|
||||
resolution: {integrity: sha512-RyWSb5AHmGtjjNQ6gIlA67sHOsWpsbWpwDokLwTcejVdOjEkJZh7QKu14J00gDDVSh8kGH4KYC/TNBceXFZhtw==}
|
||||
engines: {node: '>=18.12.0'}
|
||||
@@ -3155,14 +3295,31 @@ snapshots:
|
||||
|
||||
ansi-styles@6.2.1: {}
|
||||
|
||||
anymatch@3.1.3:
|
||||
dependencies:
|
||||
normalize-path: 3.0.0
|
||||
picomatch: 2.3.1
|
||||
|
||||
argparse@2.0.1: {}
|
||||
|
||||
assertion-error@2.0.1: {}
|
||||
|
||||
async-validator@4.2.5: {}
|
||||
|
||||
asynckit@0.4.0: {}
|
||||
|
||||
axios@1.10.0:
|
||||
dependencies:
|
||||
follow-redirects: 1.15.9
|
||||
form-data: 4.0.3
|
||||
proxy-from-env: 1.1.0
|
||||
transitivePeerDependencies:
|
||||
- debug
|
||||
|
||||
balanced-match@1.0.2: {}
|
||||
|
||||
binary-extensions@2.3.0: {}
|
||||
|
||||
birpc@2.3.0: {}
|
||||
|
||||
boolbase@1.0.0: {}
|
||||
@@ -3193,6 +3350,11 @@ snapshots:
|
||||
|
||||
cac@6.7.14: {}
|
||||
|
||||
call-bind-apply-helpers@1.0.2:
|
||||
dependencies:
|
||||
es-errors: 1.3.0
|
||||
function-bind: 1.1.2
|
||||
|
||||
callsites@3.1.0: {}
|
||||
|
||||
caniuse-lite@1.0.30001718: {}
|
||||
@@ -3212,12 +3374,28 @@ snapshots:
|
||||
|
||||
check-error@2.1.1: {}
|
||||
|
||||
chokidar@3.6.0:
|
||||
dependencies:
|
||||
anymatch: 3.1.3
|
||||
braces: 3.0.3
|
||||
glob-parent: 5.1.2
|
||||
is-binary-path: 2.1.0
|
||||
is-glob: 4.0.3
|
||||
normalize-path: 3.0.0
|
||||
readdirp: 3.6.0
|
||||
optionalDependencies:
|
||||
fsevents: 2.3.3
|
||||
|
||||
color-convert@2.0.1:
|
||||
dependencies:
|
||||
color-name: 1.1.4
|
||||
|
||||
color-name@1.1.4: {}
|
||||
|
||||
combined-stream@1.0.8:
|
||||
dependencies:
|
||||
delayed-stream: 1.0.0
|
||||
|
||||
commander@10.0.1: {}
|
||||
|
||||
concat-map@0.0.1: {}
|
||||
@@ -3291,6 +3469,14 @@ snapshots:
|
||||
|
||||
define-lazy-prop@3.0.0: {}
|
||||
|
||||
delayed-stream@1.0.0: {}
|
||||
|
||||
dunder-proto@1.0.1:
|
||||
dependencies:
|
||||
call-bind-apply-helpers: 1.0.2
|
||||
es-errors: 1.3.0
|
||||
gopd: 1.2.0
|
||||
|
||||
eastasianwidth@0.2.0: {}
|
||||
|
||||
editorconfig@1.0.4:
|
||||
@@ -3312,8 +3498,23 @@ snapshots:
|
||||
|
||||
error-stack-parser-es@0.1.5: {}
|
||||
|
||||
es-define-property@1.0.1: {}
|
||||
|
||||
es-errors@1.3.0: {}
|
||||
|
||||
es-module-lexer@1.7.0: {}
|
||||
|
||||
es-object-atoms@1.1.1:
|
||||
dependencies:
|
||||
es-errors: 1.3.0
|
||||
|
||||
es-set-tostringtag@2.1.0:
|
||||
dependencies:
|
||||
es-errors: 1.3.0
|
||||
get-intrinsic: 1.3.0
|
||||
has-tostringtag: 1.0.2
|
||||
hasown: 2.0.2
|
||||
|
||||
esbuild@0.25.4:
|
||||
optionalDependencies:
|
||||
'@esbuild/aix-ppc64': 0.25.4
|
||||
@@ -3516,11 +3717,21 @@ snapshots:
|
||||
|
||||
flatted@3.3.3: {}
|
||||
|
||||
follow-redirects@1.15.9: {}
|
||||
|
||||
foreground-child@3.3.1:
|
||||
dependencies:
|
||||
cross-spawn: 7.0.6
|
||||
signal-exit: 4.1.0
|
||||
|
||||
form-data@4.0.3:
|
||||
dependencies:
|
||||
asynckit: 0.4.0
|
||||
combined-stream: 1.0.8
|
||||
es-set-tostringtag: 2.1.0
|
||||
hasown: 2.0.2
|
||||
mime-types: 2.1.35
|
||||
|
||||
fs-extra@11.3.0:
|
||||
dependencies:
|
||||
graceful-fs: 4.2.11
|
||||
@@ -3530,8 +3741,28 @@ snapshots:
|
||||
fsevents@2.3.3:
|
||||
optional: true
|
||||
|
||||
function-bind@1.1.2: {}
|
||||
|
||||
gensync@1.0.0-beta.2: {}
|
||||
|
||||
get-intrinsic@1.3.0:
|
||||
dependencies:
|
||||
call-bind-apply-helpers: 1.0.2
|
||||
es-define-property: 1.0.1
|
||||
es-errors: 1.3.0
|
||||
es-object-atoms: 1.1.1
|
||||
function-bind: 1.1.2
|
||||
get-proto: 1.0.1
|
||||
gopd: 1.2.0
|
||||
has-symbols: 1.1.0
|
||||
hasown: 2.0.2
|
||||
math-intrinsics: 1.1.0
|
||||
|
||||
get-proto@1.0.1:
|
||||
dependencies:
|
||||
dunder-proto: 1.0.1
|
||||
es-object-atoms: 1.1.1
|
||||
|
||||
get-stream@9.0.1:
|
||||
dependencies:
|
||||
'@sec-ant/readable-stream': 0.4.1
|
||||
@@ -3558,6 +3789,8 @@ snapshots:
|
||||
|
||||
globals@14.0.0: {}
|
||||
|
||||
gopd@1.2.0: {}
|
||||
|
||||
graceful-fs@4.2.11: {}
|
||||
|
||||
graphemer@1.4.0: {}
|
||||
@@ -3566,6 +3799,16 @@ snapshots:
|
||||
|
||||
has-flag@4.0.0: {}
|
||||
|
||||
has-symbols@1.1.0: {}
|
||||
|
||||
has-tostringtag@1.0.2:
|
||||
dependencies:
|
||||
has-symbols: 1.1.0
|
||||
|
||||
hasown@2.0.2:
|
||||
dependencies:
|
||||
function-bind: 1.1.2
|
||||
|
||||
he@1.2.0: {}
|
||||
|
||||
highlight.js@11.11.1: {}
|
||||
@@ -3609,6 +3852,10 @@ snapshots:
|
||||
|
||||
ini@1.3.8: {}
|
||||
|
||||
is-binary-path@2.1.0:
|
||||
dependencies:
|
||||
binary-extensions: 2.3.0
|
||||
|
||||
is-docker@3.0.0: {}
|
||||
|
||||
is-extglob@2.1.1: {}
|
||||
@@ -3753,6 +4000,8 @@ snapshots:
|
||||
dependencies:
|
||||
'@jridgewell/sourcemap-codec': 1.5.0
|
||||
|
||||
math-intrinsics@1.1.0: {}
|
||||
|
||||
memorystream@0.3.1: {}
|
||||
|
||||
merge2@1.4.1: {}
|
||||
@@ -3762,6 +4011,12 @@ snapshots:
|
||||
braces: 3.0.3
|
||||
picomatch: 2.3.1
|
||||
|
||||
mime-db@1.52.0: {}
|
||||
|
||||
mime-types@2.1.35:
|
||||
dependencies:
|
||||
mime-db: 1.52.0
|
||||
|
||||
minimatch@3.1.2:
|
||||
dependencies:
|
||||
brace-expansion: 1.1.11
|
||||
@@ -3826,6 +4081,8 @@ snapshots:
|
||||
dependencies:
|
||||
abbrev: 2.0.0
|
||||
|
||||
normalize-path@3.0.0: {}
|
||||
|
||||
npm-normalize-package-bin@4.0.0: {}
|
||||
|
||||
npm-run-all2@7.0.2:
|
||||
@@ -3957,6 +4214,8 @@ snapshots:
|
||||
|
||||
proto-list@1.2.4: {}
|
||||
|
||||
proxy-from-env@1.1.0: {}
|
||||
|
||||
punycode@2.3.1: {}
|
||||
|
||||
quansync@0.2.10: {}
|
||||
@@ -3968,6 +4227,10 @@ snapshots:
|
||||
json-parse-even-better-errors: 4.0.0
|
||||
npm-normalize-package-bin: 4.0.0
|
||||
|
||||
readdirp@3.6.0:
|
||||
dependencies:
|
||||
picomatch: 2.3.1
|
||||
|
||||
resolve-from@4.0.0: {}
|
||||
|
||||
reusify@1.1.0: {}
|
||||
@@ -4099,6 +4362,11 @@ snapshots:
|
||||
fdir: 6.4.4(picomatch@4.0.2)
|
||||
picomatch: 4.0.2
|
||||
|
||||
tinyglobby@0.2.14:
|
||||
dependencies:
|
||||
fdir: 6.4.4(picomatch@4.0.2)
|
||||
picomatch: 4.0.2
|
||||
|
||||
tinypool@1.0.2: {}
|
||||
|
||||
tinyrainbow@2.0.0: {}
|
||||
@@ -4186,6 +4454,22 @@ snapshots:
|
||||
pathe: 2.0.3
|
||||
picomatch: 4.0.2
|
||||
|
||||
unplugin-vue-components@28.7.0(@babel/parser@7.27.2)(vue@3.5.14(typescript@5.8.3)):
|
||||
dependencies:
|
||||
chokidar: 3.6.0
|
||||
debug: 4.4.1
|
||||
local-pkg: 1.1.1
|
||||
magic-string: 0.30.17
|
||||
mlly: 1.7.4
|
||||
tinyglobby: 0.2.14
|
||||
unplugin: 2.3.5
|
||||
unplugin-utils: 0.2.4
|
||||
vue: 3.5.14(typescript@5.8.3)
|
||||
optionalDependencies:
|
||||
'@babel/parser': 7.27.2
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
|
||||
unplugin@2.3.5:
|
||||
dependencies:
|
||||
acorn: 8.14.1
|
||||
|
||||
@@ -28,23 +28,23 @@
|
||||
|
||||
/* ========== 颜色定义 - 亮色主题(默认) ========== */
|
||||
/* 背景色层级 */
|
||||
--bg-primary: #ffffff; /* 主背景色 */
|
||||
--bg-secondary: #f8fafc; /* 次级背景 */
|
||||
--bg-tertiary: #f1f5f9; /* 三级背景 */
|
||||
--bg-quaternary: #e2e8f0; /* 四级背景 */
|
||||
--bg-overlay: rgba(255, 255, 255, 0.95); /* 遮罩层 */
|
||||
--bg-glass: rgba(248, 250, 252, 0.8); /* 玻璃效果 */
|
||||
--bg-card: rgba(241, 245, 249, 0.8); /* 卡片背景 */
|
||||
--bg-hover: rgba(59, 130, 246, 0.08); /* 悬停背景 */
|
||||
--bg-selected: rgba(59, 130, 246, 0.15); /* 选中背景 */
|
||||
--bg-primary: #ffffff;
|
||||
--bg-secondary: #f8fafc;
|
||||
--bg-tertiary: #f1f5f9;
|
||||
--bg-quaternary: #e2e8f0;
|
||||
--bg-overlay: rgba(255, 255, 255, 0.95);
|
||||
--bg-glass: rgba(248, 250, 252, 0.8);
|
||||
--bg-card: rgba(241, 245, 249, 0.8);
|
||||
--bg-hover: rgba(59, 130, 246, 0.08);
|
||||
--bg-selected: rgba(59, 130, 246, 0.15);
|
||||
|
||||
/* 文字色层级 */
|
||||
--text-primary: #0f172a; /* 主文字色 */
|
||||
--text-secondary: #1e293b; /* 次级文字 */
|
||||
--text-tertiary: #334155; /* 三级文字 */
|
||||
--text-quaternary: #475569; /* 四级文字 */
|
||||
--text-muted: #64748b; /* 柔和文字 */
|
||||
--text-disabled: #94a3b8; /* 禁用文字 */
|
||||
--text-primary: #0f172a;
|
||||
--text-secondary: #1e293b;
|
||||
--text-tertiary: #334155;
|
||||
--text-quaternary: #475569;
|
||||
--text-muted: #64748b;
|
||||
--text-disabled: #94a3b8;
|
||||
|
||||
/* 边框色层级 */
|
||||
--border-primary: #e2e8f0;
|
||||
@@ -54,12 +54,12 @@
|
||||
--border-focus: #3b82f6;
|
||||
|
||||
/* 主题色 - 这些在明暗主题中保持一致 */
|
||||
--accent-primary: #3b82f6; /* 主要强调色 - 蓝色 */
|
||||
--accent-secondary: #06b6d4; /* 次要强调色 - 青色 */
|
||||
--accent-success: #22c55e; /* 成功 - 绿色 */
|
||||
--accent-warning: #f59e0b; /* 警告 - 橙色 */
|
||||
--accent-error: #ef4444; /* 错误 - 红色 */
|
||||
--accent-purple: #8b5cf6; /* 紫色 */
|
||||
--accent-primary: #3b82f6;
|
||||
--accent-secondary: #06b6d4;
|
||||
--accent-success: #22c55e;
|
||||
--accent-warning: #f59e0b;
|
||||
--accent-error: #ef4444;
|
||||
--accent-purple: #8b5cf6;
|
||||
|
||||
/* 阴影 */
|
||||
--shadow-sm: 0 1px 2px 0 rgba(0, 0, 0, 0.05);
|
||||
@@ -94,63 +94,16 @@
|
||||
|
||||
/* 布局 */
|
||||
--section-gap: 160px;
|
||||
|
||||
/* 监控页面软件列表选中样式颜色 */
|
||||
--monitor-bg-card-selected: rgba(var(--accent-primary), 0.05);
|
||||
--monitor-accent-primary-alpha: rgba(var(--accent-primary), 0.2);
|
||||
}
|
||||
|
||||
/* ==================== 暗色主题 - .dark 类名方式 ==================== */
|
||||
.dark {
|
||||
/* 背景色层级 - 暗色 */
|
||||
--bg-primary: #0f172a;
|
||||
--bg-secondary: #1e293b;
|
||||
--bg-tertiary: #334155;
|
||||
--bg-quaternary: #475569;
|
||||
--bg-overlay: rgba(15, 23, 42, 0.95);
|
||||
--bg-glass: rgba(30, 41, 59, 0.8);
|
||||
--bg-card: rgba(51, 65, 85, 0.5);
|
||||
--bg-hover: rgba(59, 130, 246, 0.1);
|
||||
--bg-selected: rgba(59, 130, 246, 0.2);
|
||||
|
||||
/* 文字色层级 - 暗色 */
|
||||
--text-primary: #f8fafc;
|
||||
--text-secondary: #f1f5f9;
|
||||
--text-tertiary: #e2e8f0;
|
||||
--text-quaternary: #cbd5e1;
|
||||
--text-muted: #94a3b8;
|
||||
--text-disabled: #64748b;
|
||||
|
||||
/* 边框色层级 - 暗色 */
|
||||
--border-primary: #334155;
|
||||
--border-secondary: rgba(51, 65, 85, 0.3);
|
||||
--border-tertiary: rgba(71, 85, 105, 0.3);
|
||||
--border-hover: rgba(59, 130, 246, 0.5);
|
||||
--border-focus: #3b82f6;
|
||||
|
||||
/* 阴影 - 暗色模式 */
|
||||
--shadow-sm: 0 1px 2px 0 rgba(0, 0, 0, 0.3);
|
||||
--shadow-md: 0 4px 6px -1px rgba(0, 0, 0, 0.4);
|
||||
--shadow-lg: 0 10px 15px -3px rgba(0, 0, 0, 0.5);
|
||||
--shadow-xl: 0 20px 25px -5px rgba(0, 0, 0, 0.6);
|
||||
|
||||
/* 滚动条颜色 - 暗色主题 */
|
||||
--scrollbar-track-bg: rgba(255, 255, 255, 0.03);
|
||||
--scrollbar-thumb-bg: rgba(255, 255, 255, 0.2);
|
||||
--scrollbar-thumb-bg-hover: rgba(255, 255, 255, 0.35);
|
||||
--scrollbar-thumb-bg-active: rgba(255, 255, 255, 0.45);
|
||||
--scrollbar-thumb-border: rgba(255, 255, 255, 0.1);
|
||||
--scrollbar-thumb-border-hover: rgba(255, 255, 255, 0.2);
|
||||
--scrollbar-thumb-border-active: rgba(255, 255, 255, 0.3);
|
||||
--scrollbar-corner-bg: rgba(255, 255, 255, 0.03);
|
||||
|
||||
/* 语义化颜色变量(向后兼容)*/
|
||||
--color-background: var(--bg-primary);
|
||||
--color-background-soft: var(--bg-secondary);
|
||||
--color-background-mute: var(--bg-tertiary);
|
||||
--color-border: var(--border-primary);
|
||||
--color-border-hover: var(--border-hover);
|
||||
--color-heading: var(--text-primary);
|
||||
--color-text: var(--text-secondary);
|
||||
}
|
||||
|
||||
/* ==================== 暗色主题 - data-theme 属性方式(向后兼容) ==================== */
|
||||
/* ==================== 暗色主题变量定义 ==================== */
|
||||
/* 暗色主题 - .dark 类名方式 */
|
||||
.dark,
|
||||
/* 暗色主题 - data-theme 属性方式(向后兼容) */
|
||||
[data-theme="dark"] {
|
||||
/* 背景色层级 - 暗色 */
|
||||
--bg-primary: #0f172a;
|
||||
@@ -202,6 +155,10 @@
|
||||
--color-border-hover: var(--border-hover);
|
||||
--color-heading: var(--text-primary);
|
||||
--color-text: var(--text-secondary);
|
||||
|
||||
/* 监控页面软件列表选中样式颜色 */
|
||||
--monitor-bg-card-selected: rgba(var(--accent-primary), 0.1);
|
||||
|
||||
}
|
||||
|
||||
/* ==================== 媒体查询 - 系统主题偏好 ==================== */
|
||||
@@ -257,15 +214,16 @@
|
||||
--color-border-hover: var(--border-hover);
|
||||
--color-heading: var(--text-primary);
|
||||
--color-text: var(--text-secondary);
|
||||
|
||||
/* 监控页面软件列表选中样式颜色 */
|
||||
--monitor-bg-card-selected: rgba(var(--accent-primary), 0.1);
|
||||
}
|
||||
}
|
||||
|
||||
/* ==================== 主题切换过渡效果 ==================== */
|
||||
* {
|
||||
/* 确保所有元素都使用主题过渡 */
|
||||
transition: background-color 0.2s ease,
|
||||
border-color 0.2s ease,
|
||||
color 0.2s ease;
|
||||
transition: background-color 0.2s ease, border-color 0.2s ease, color 0.2s ease;
|
||||
}
|
||||
|
||||
/* 防止页面初始加载时的闪烁 */
|
||||
|
||||
@@ -0,0 +1,67 @@
|
||||
/**
|
||||
* Time:2025/6/15 20:13 49
|
||||
* Name:httpConfig.ts
|
||||
* Path:src/config
|
||||
* ProjectName:argus-front
|
||||
* Author:charlatans
|
||||
*
|
||||
* Il n'ya qu'un héroïsme au monde :
|
||||
* c'est de voir le monde tel qu'il est et de l'aimer.
|
||||
*/
|
||||
import type { HttpConfig } from '@/types/http.ts'
|
||||
|
||||
// 2. 配置管理器 (config/httpConfig.ts)
|
||||
class HttpConfigManager {
|
||||
private config: HttpConfig = {
|
||||
baseURL: import.meta.env.VITE_APP_API_URL || 'http://localhost:8726',
|
||||
timeout: 10000,
|
||||
headers: {
|
||||
'Content-Type': 'application/json'
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* 设置配置
|
||||
*/
|
||||
setConfig(config: Partial<HttpConfig>): void {
|
||||
this.config = { ...this.config, ...config };
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取配置
|
||||
*/
|
||||
getConfig(): HttpConfig {
|
||||
return { ...this.config };
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置基础URL
|
||||
*/
|
||||
setBaseURL(baseURL: string): void {
|
||||
this.config.baseURL = baseURL;
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置端口
|
||||
*/
|
||||
setPort(host: string, port: number): void {
|
||||
const protocol = this.config.baseURL.startsWith('https') ? 'https' : 'http';
|
||||
this.config.baseURL = `${protocol}://${host}:${port}`;
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置超时时间
|
||||
*/
|
||||
setTimeout(timeout: number): void {
|
||||
this.config.timeout = timeout;
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置默认请求头
|
||||
*/
|
||||
setHeaders(headers: Record<string, string>): void {
|
||||
this.config.headers = { ...this.config.headers, ...headers };
|
||||
}
|
||||
}
|
||||
|
||||
export const httpConfig = new HttpConfigManager();
|
||||
@@ -10,6 +10,8 @@ import websocketPlugin from '@/plugins/websocketPlugin'
|
||||
import { useWebSocketStore } from '@/stores/websocketStore'
|
||||
import { createNaiveUI } from './naive'
|
||||
import { useThemeStore } from '@/stores/theme'
|
||||
import { useUuidStore } from '@/stores/uuidStore'
|
||||
import { logB } from '@/utils/logHelper/logUtils'
|
||||
|
||||
const app = createApp(App)
|
||||
app.use(createPinia())
|
||||
@@ -21,6 +23,14 @@ app.use(createNaiveUI())
|
||||
// 这行代码会触发 store 的初始化,从而立即应用主题
|
||||
useThemeStore()
|
||||
|
||||
// 获取全局 UUID
|
||||
const useUuidStore1 = useUuidStore()
|
||||
logB.success('全局 ID :', useUuidStore1.uuid)
|
||||
|
||||
// http 注册
|
||||
import httpPlugin from './plugins/http';
|
||||
app.use(httpPlugin);
|
||||
|
||||
app.mount('#app')
|
||||
|
||||
// 注册 C# 函数
|
||||
@@ -31,16 +41,20 @@ const webSocketStore = useWebSocketStore()
|
||||
|
||||
// 监听WebSocket地址
|
||||
const bridge = CSharpBridgeV2?.getBridge()
|
||||
|
||||
const intervalId = setInterval(() => {
|
||||
if (webSocketStore.isInitialized) {
|
||||
clearInterval(intervalId)
|
||||
return
|
||||
}
|
||||
if (bridge){
|
||||
bridge.send('GetWebSocketPath', {}, (data) => {
|
||||
webSocketStore.initialize(data)
|
||||
console.log(data, '======')
|
||||
})
|
||||
}
|
||||
}, 500)
|
||||
if (bridge) {
|
||||
const intervalId = setInterval(() => {
|
||||
if (webSocketStore.isInitialized) {
|
||||
clearInterval(intervalId)
|
||||
return
|
||||
}
|
||||
if (bridge) {
|
||||
bridge.send('GetWebSocketPath', {}, (data) => {
|
||||
webSocketStore.initialize(data)
|
||||
console.log(data, '======')
|
||||
})
|
||||
}
|
||||
}, 500)
|
||||
} else {
|
||||
// todo: 2025/6/25 08:32 开发阶段直接使用固定节点
|
||||
webSocketStore.initialize('ws://127.0.0.1:8267')
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
/**
|
||||
* Time:2025/6/15 20:23 36
|
||||
* Name:http.ts
|
||||
* Path:src/plugins
|
||||
* ProjectName:argus-front
|
||||
* Author:charlatans
|
||||
*
|
||||
* Il n'ya qu'un héroïsme au monde :
|
||||
* c'est de voir le monde tel qu'il est et de l'aimer.
|
||||
*/
|
||||
import { type App } from 'vue';
|
||||
import { httpConfig } from '@/config/httpConfig.ts'
|
||||
import { httpClient } from '@/utils/http.ts'
|
||||
|
||||
export default {
|
||||
install(app: App) {
|
||||
// 更新HTTP配置
|
||||
const config = httpConfig.getConfig();
|
||||
httpClient.updateConfig(config);
|
||||
|
||||
// 注册全局属性
|
||||
app.config.globalProperties.$http = httpClient;
|
||||
app.config.globalProperties.$httpConfig = httpConfig;
|
||||
|
||||
// 提供注入
|
||||
app.provide('$http', httpClient);
|
||||
app.provide('$httpConfig', httpConfig);
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,16 @@
|
||||
import { ref, computed } from 'vue'
|
||||
import { defineStore } from 'pinia'
|
||||
import lodash from 'lodash'
|
||||
|
||||
export const useUuidStore = defineStore('uuid', () => {
|
||||
const _uuid: ref = ref('')
|
||||
|
||||
const uuid = computed(() => {
|
||||
if (lodash.isEmpty(_uuid.value)) {
|
||||
_uuid.value = crypto.randomUUID()
|
||||
}
|
||||
return _uuid.value
|
||||
})
|
||||
|
||||
return { uuid }
|
||||
})
|
||||
+12
@@ -0,0 +1,12 @@
|
||||
/**
|
||||
* 响应模型
|
||||
*/
|
||||
interface ResponseModel {
|
||||
success: boolean,
|
||||
data: unknown,
|
||||
message: string
|
||||
}
|
||||
|
||||
|
||||
|
||||
export { ResponseModel }
|
||||
@@ -0,0 +1,292 @@
|
||||
import axios, {
|
||||
type AxiosInstance,
|
||||
type AxiosRequestConfig,
|
||||
type AxiosResponse,
|
||||
AxiosError,
|
||||
type InternalAxiosRequestConfig,
|
||||
} from 'axios'
|
||||
// 或者混合导入(如果同时需要导入值和类型)
|
||||
import type { ApiResponse, HttpConfig, RequestConfig } from '@/types/http.ts'
|
||||
import { disLog, logB, logN, logS } from '@/utils/logHelper/logUtils'
|
||||
|
||||
class HttpClient {
|
||||
private axiosInstance: AxiosInstance
|
||||
private pending: Map<string, AbortController> = new Map()
|
||||
|
||||
constructor() {
|
||||
this.axiosInstance = axios.create()
|
||||
this.setupInterceptors()
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新配置
|
||||
*/
|
||||
updateConfig(config: HttpConfig): void {
|
||||
this.axiosInstance.defaults.baseURL = config.baseURL
|
||||
this.axiosInstance.defaults.timeout = config.timeout || 10000
|
||||
this.axiosInstance.defaults.headers.common = {
|
||||
...this.axiosInstance.defaults.headers.common,
|
||||
...config.headers,
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 生成请求标识符
|
||||
*/
|
||||
private getRequestKey(config: AxiosRequestConfig): string {
|
||||
return `${config.method?.toUpperCase()}_${config.url}_${JSON.stringify(
|
||||
config.params,
|
||||
)}_${JSON.stringify(config.data)}`
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加请求到待处理列表
|
||||
*/
|
||||
private addPending(config: InternalAxiosRequestConfig): void {
|
||||
const requestKey = this.getRequestKey(config)
|
||||
config.signal = new AbortController().signal
|
||||
|
||||
if (this.pending.has(requestKey)) {
|
||||
this.pending.get(requestKey)?.abort()
|
||||
}
|
||||
|
||||
const controller = new AbortController()
|
||||
config.signal = controller.signal
|
||||
this.pending.set(requestKey, controller)
|
||||
}
|
||||
|
||||
/**
|
||||
* 移除请求从待处理列表
|
||||
*/
|
||||
private removePending(config: AxiosRequestConfig): void {
|
||||
const requestKey = this.getRequestKey(config)
|
||||
if (this.pending.has(requestKey)) {
|
||||
this.pending.delete(requestKey)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置拦截器
|
||||
*/
|
||||
private setupInterceptors(): void {
|
||||
// 请求拦截器
|
||||
this.axiosInstance.interceptors.request.use(
|
||||
(config: InternalAxiosRequestConfig) => {
|
||||
console.group(
|
||||
'请求链接: ' +
|
||||
config.url +
|
||||
' ' +
|
||||
config.method?.toUpperCase() +
|
||||
' params: ' +
|
||||
JSON.stringify(config.params) +
|
||||
', data: ' +
|
||||
JSON.stringify(config.data),
|
||||
)
|
||||
// 防止重复请求
|
||||
this.addPending(config)
|
||||
|
||||
// 添加时间戳防止缓存
|
||||
if (config.method?.toLowerCase() === 'get') {
|
||||
config.params = {
|
||||
...config.params,
|
||||
_t: Date.now(),
|
||||
}
|
||||
}
|
||||
|
||||
// 添加token
|
||||
const token = localStorage.getItem('token')
|
||||
if (token) {
|
||||
config.headers.Authorization = `Bearer ${token}`
|
||||
}
|
||||
|
||||
logB.success('请求发送:', config)
|
||||
return config
|
||||
},
|
||||
(error: AxiosError) => {
|
||||
logB.error('请求错误:', error)
|
||||
return Promise.reject(error)
|
||||
},
|
||||
)
|
||||
|
||||
// 响应拦截器
|
||||
this.axiosInstance.interceptors.response.use(
|
||||
(response: AxiosResponse<ApiResponse>) => {
|
||||
this.removePending(response.config)
|
||||
|
||||
logB.success('响应接收:', response)
|
||||
|
||||
// 统一处理响应数据
|
||||
const { data } = response
|
||||
|
||||
console.groupEnd()
|
||||
if (data.success || data.code === 200) {
|
||||
return response
|
||||
} else {
|
||||
// 业务错误处理
|
||||
const errorMessage = data.message || '请求失败'
|
||||
return Promise.reject(new Error(errorMessage))
|
||||
}
|
||||
},
|
||||
(error: AxiosError<ApiResponse>) => {
|
||||
this.removePending(error.config || {})
|
||||
|
||||
logB.error('响应错误:', error)
|
||||
|
||||
// 统一错误处理
|
||||
this.handleError(error)
|
||||
console.groupEnd()
|
||||
return Promise.reject(error)
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* 统一错误处理
|
||||
*/
|
||||
private handleError(error: AxiosError<ApiResponse>): void {
|
||||
let message = '网络错误'
|
||||
|
||||
if (error.response) {
|
||||
const { status, data } = error.response
|
||||
|
||||
switch (status) {
|
||||
case 400:
|
||||
message = data?.message || '请求参数错误'
|
||||
break
|
||||
case 401:
|
||||
message = '未授权,请重新登录'
|
||||
// 清除token并跳转到登录页
|
||||
localStorage.removeItem('token')
|
||||
// router.push('/login');
|
||||
break
|
||||
case 403:
|
||||
message = '拒绝访问'
|
||||
break
|
||||
case 404:
|
||||
message = '请求的资源不存在'
|
||||
break
|
||||
case 500:
|
||||
message = '服务器内部错误'
|
||||
break
|
||||
default:
|
||||
message = data?.message || `错误码: ${status}`
|
||||
}
|
||||
} else if (error.code === 'ECONNABORTED') {
|
||||
message = '请求超时'
|
||||
} else if (error.message.includes('Network Error')) {
|
||||
message = '网络连接异常'
|
||||
}
|
||||
logB.error(message)
|
||||
}
|
||||
|
||||
/**
|
||||
* 通用请求方法
|
||||
*/
|
||||
async request<T = unknown>(config: RequestConfig): Promise<ApiResponse<T>> {
|
||||
try {
|
||||
const response = await this.axiosInstance.request<ApiResponse<T>>(config)
|
||||
return response.data
|
||||
} catch (error) {
|
||||
throw error
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* GET请求
|
||||
*/
|
||||
async get<T = unknown>(
|
||||
url: string,
|
||||
params?: unknown,
|
||||
config?: AxiosRequestConfig,
|
||||
): Promise<ApiResponse<T>> {
|
||||
return this.request<T>({
|
||||
url,
|
||||
method: 'GET',
|
||||
params,
|
||||
...config,
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* POST请求
|
||||
*/
|
||||
async post<T = unknown>(
|
||||
url: string,
|
||||
data?: unknown,
|
||||
config?: AxiosRequestConfig,
|
||||
): Promise<ApiResponse<T>> {
|
||||
return this.request<T>({
|
||||
url,
|
||||
method: 'POST',
|
||||
data,
|
||||
...config,
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* PUT请求
|
||||
*/
|
||||
async put<T = unknown>(
|
||||
url: string,
|
||||
data?: unknown,
|
||||
config?: AxiosRequestConfig,
|
||||
): Promise<ApiResponse<T>> {
|
||||
return this.request<T>({
|
||||
url,
|
||||
method: 'PUT',
|
||||
data,
|
||||
...config,
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* DELETE请求
|
||||
*/
|
||||
async delete<T = unknown>(
|
||||
url: string,
|
||||
params?: unknown,
|
||||
config?: AxiosRequestConfig,
|
||||
): Promise<ApiResponse<T>> {
|
||||
return this.request<T>({
|
||||
url,
|
||||
method: 'DELETE',
|
||||
params,
|
||||
...config,
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* PATCH请求
|
||||
*/
|
||||
async patch<T = unknown>(
|
||||
url: string,
|
||||
data?: unknown,
|
||||
config?: AxiosRequestConfig,
|
||||
): Promise<ApiResponse<T>> {
|
||||
return this.request<T>({
|
||||
url,
|
||||
method: 'PATCH',
|
||||
data,
|
||||
...config,
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 取消所有请求
|
||||
*/
|
||||
cancelAllRequests(): void {
|
||||
this.pending.forEach((controller) => {
|
||||
controller.abort()
|
||||
})
|
||||
this.pending.clear()
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取Axios实例
|
||||
*/
|
||||
getAxiosInstance(): AxiosInstance {
|
||||
return this.axiosInstance
|
||||
}
|
||||
}
|
||||
|
||||
export const httpClient = new HttpClient()
|
||||
@@ -2,6 +2,8 @@ import { CommandHandler, SubscriptionRequest, WebSocketMessage, WebSocketRespons
|
||||
import CSharpBridgeV2 from '@/correspond/CSharpBridgeV2'
|
||||
import { ref } from 'vue'
|
||||
import { WebSocketState } from '@/types/websocket'
|
||||
import { logB } from '@/utils/logHelper/logUtils'
|
||||
import { useUuidStore } from '@/stores/uuidStore'
|
||||
|
||||
export class WebSocketManager {
|
||||
private socket: WebSocket | null = null
|
||||
@@ -33,15 +35,21 @@ export class WebSocketManager {
|
||||
|
||||
// 初始化WebSocket连接
|
||||
public initialize(url: string) {
|
||||
console.log('initialize', url)
|
||||
logB.info('进入 web Socket 初始化, url:', url)
|
||||
if (url.trim() === '') return
|
||||
if (this.socket) return
|
||||
this.state = WebSocketState.CONNECTING
|
||||
this.socket = new WebSocket(url)
|
||||
const useUuidStore1 = useUuidStore()
|
||||
logB.info('准备建立连接, uuid:', useUuidStore1.uuid)
|
||||
|
||||
const url1 = url + '?uuid=' + useUuidStore1.uuid
|
||||
logB.info('拼接链接:', url1)
|
||||
this.socket = new WebSocket(url1)
|
||||
|
||||
this.isInitialized = true
|
||||
|
||||
this.registerHandler('welcome', (data: WebSocketResponse) => {
|
||||
if (data.success) console.log('WebSocket 连接建立成功 !! ')
|
||||
if (data.success) logB.success('WebSocket 连接建立成功 !! ')
|
||||
else console.error('收到WbeSocket 欢迎信息,但是解析失败!!1')
|
||||
})
|
||||
|
||||
@@ -49,7 +57,7 @@ export class WebSocketManager {
|
||||
this.state = WebSocketState.CONNECTED
|
||||
this.isReconnecting = true
|
||||
this.reconnectAttempts = 0
|
||||
console.log('WebSocket connected')
|
||||
logB.success('WebSocket connected')
|
||||
// 发送队列中的消息
|
||||
this.flushMessageQueue()
|
||||
// 重新激活订阅
|
||||
|
||||
@@ -1,85 +1,206 @@
|
||||
<template>
|
||||
<div class="sidebar scrollbar-primary scrollbar-thin" :style="{ width: width + 'px' }">
|
||||
<div class="sidebar-content">
|
||||
<template v-if="false">
|
||||
<div class="sidebar-header">
|
||||
<h3 class="sidebar-title">系统概览</h3>
|
||||
<div class="sidebar-badge">{{ data.processCount }}</div>
|
||||
</div>
|
||||
|
||||
<div class="sidebar-stats">
|
||||
<span>使用 echarts 绘制当前网速</span>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<div class="sidebar-header">
|
||||
<h3 class="sidebar-title">系统概览</h3>
|
||||
<div class="sidebar-badge">{{ data.processCount }}</div>
|
||||
<h3 class="sidebar-title">所有连接</h3>
|
||||
</div>
|
||||
|
||||
<div class="sidebar-stats">
|
||||
<div class="stat-card">
|
||||
<div class="stat-icon">🔗</div>
|
||||
<div class="stat-info">
|
||||
<div class="stat-value">{{ data.activeConnections }}</div>
|
||||
<div class="stat-label">活跃连接</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- 应用列表 -->
|
||||
<div class="app-list">
|
||||
<div
|
||||
v-for="app in applications"
|
||||
:key="app.id"
|
||||
class="app-item"
|
||||
:class="{ 'app-item--selected': selectedApp?.id === app.id }"
|
||||
@click="selectApp(app)"
|
||||
@mouseenter="handleMouseEnter"
|
||||
@mouseleave="handleMouseLeave"
|
||||
>
|
||||
<!-- 书角折叠效果 -->
|
||||
<div v-if="selectedApp?.id === app.id" class="folded-corner"></div>
|
||||
|
||||
<div class="stat-card">
|
||||
<div class="stat-icon">⚡</div>
|
||||
<div class="stat-info">
|
||||
<div class="stat-value">{{ data.networkSpeed }}</div>
|
||||
<div class="stat-label">网络速度</div>
|
||||
<!-- 应用图标 -->
|
||||
<div class="app-icon">
|
||||
<img :src="app.icon" :alt="app.name" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="stat-card">
|
||||
<div class="stat-icon">🛡️</div>
|
||||
<div class="stat-info">
|
||||
<div class="stat-value">{{ data.ruleCount }}</div>
|
||||
<div class="stat-label">防护规则</div>
|
||||
<!-- 应用信息 -->
|
||||
<div class="app-info">
|
||||
<div class="app-name">{{ app.name }}</div>
|
||||
<div class="app-details">
|
||||
<span class="app-detail">PID: {{ app.pid }}</span>
|
||||
<span class="app-detail">内存: {{ app.memory }}</span>
|
||||
<span class="app-detail">{{ app.status }}</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 应用状态指示器 -->
|
||||
<div class="app-status">
|
||||
<div class="status-indicator" :class="`status-${app.statusType}`"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="sidebar-section">
|
||||
<h4 class="section-title">快速操作</h4>
|
||||
<div class="quick-actions">
|
||||
<div class="action-item" @click="handleAction('scan')">扫描威胁</div>
|
||||
<div class="action-item" @click="handleAction('update')">更新规则</div>
|
||||
<div class="action-item" @click="handleAction('export')">导出日志</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="sidebar-section">
|
||||
<h4 class="section-title">系统状态</h4>
|
||||
<div class="system-status">
|
||||
<div class="status-item">
|
||||
<span class="status-dot active"></span>
|
||||
<span class="status-label">防护已启用</span>
|
||||
</div>
|
||||
<div class="status-item">
|
||||
<span class="status-dot active"></span>
|
||||
<span class="status-label">实时监控中</span>
|
||||
</div>
|
||||
<div class="status-item">
|
||||
<span class="status-dot warning"></span>
|
||||
<span class="status-label">待处理警告: 3</span>
|
||||
</div>
|
||||
</div>
|
||||
<!-- 空状态 -->
|
||||
<div v-if="applications.length === 0" class="empty-state">
|
||||
<n-icon :component="DesktopOutline" size="48" class="empty-icon" />
|
||||
<div class="empty-title">暂无运行的应用</div>
|
||||
<div class="empty-subtitle">系统中没有检测到正在运行的应用程序</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { defineProps, defineEmits } from 'vue'
|
||||
import { ref, defineEmits, defineProps } from 'vue'
|
||||
import { NIcon } from 'naive-ui'
|
||||
import { CheckmarkOutline, DesktopOutline } from '@vicons/ionicons5'
|
||||
import { httpClient } from '@/utils/http.ts'
|
||||
import { ResponseModel } from '@/types/response'
|
||||
|
||||
// 定义应用数据类型
|
||||
interface Application {
|
||||
id: string
|
||||
name: string
|
||||
icon: string
|
||||
pid: number
|
||||
memory: string
|
||||
status: string
|
||||
statusType: 'active' | 'idle' | 'background'
|
||||
path?: string
|
||||
windowTitle?: string
|
||||
cpuUsage?: number
|
||||
}
|
||||
|
||||
// 事件定义
|
||||
const emit = defineEmits<{
|
||||
'app-selected': [app: Application | null]
|
||||
}>()
|
||||
|
||||
// 发送请求
|
||||
httpClient.post(`/subscribe`, '发送的测试例子').then((res:ResponseModel) => {
|
||||
console.log(res)
|
||||
})
|
||||
|
||||
// 选中的应用
|
||||
const selectedApp = ref<Application | null>(null)
|
||||
|
||||
// 模拟应用数据
|
||||
const applications = ref<Application[]>([
|
||||
{
|
||||
id: '1',
|
||||
name: 'Visual Studio Code',
|
||||
icon: 'https://code.visualstudio.com/assets/images/code-stable.png',
|
||||
pid: 12456,
|
||||
memory: '245.6 MB',
|
||||
status: '活跃',
|
||||
statusType: 'active',
|
||||
path: '/Applications/Visual Studio Code.app',
|
||||
windowTitle: 'main.js - myproject',
|
||||
cpuUsage: 5.2,
|
||||
},
|
||||
{
|
||||
id: '2',
|
||||
name: 'Google Chrome',
|
||||
icon: 'https://upload.wikimedia.org/wikipedia/commons/e/e1/Google_Chrome_icon_%28February_2022%29.svg',
|
||||
pid: 8923,
|
||||
memory: '512.3 MB',
|
||||
status: '活跃',
|
||||
statusType: 'active',
|
||||
path: '/Applications/Google Chrome.app',
|
||||
windowTitle: 'GitHub - Dashboard',
|
||||
cpuUsage: 12.8,
|
||||
},
|
||||
{
|
||||
id: '3',
|
||||
name: 'Spotify',
|
||||
icon: 'https://upload.wikimedia.org/wikipedia/commons/1/19/Spotify_logo_without_text.svg',
|
||||
pid: 5647,
|
||||
memory: '156.7 MB',
|
||||
status: '后台运行',
|
||||
statusType: 'background',
|
||||
path: '/Applications/Spotify.app',
|
||||
windowTitle: 'Spotify Premium',
|
||||
cpuUsage: 2.1,
|
||||
},
|
||||
{
|
||||
id: '4',
|
||||
name: 'Finder',
|
||||
icon: 'https://upload.wikimedia.org/wikipedia/en/f/f4/MacOS_Finder_Icon.png',
|
||||
pid: 1234,
|
||||
memory: '89.2 MB',
|
||||
status: '空闲',
|
||||
statusType: 'idle',
|
||||
path: '/System/Library/CoreServices/Finder.app',
|
||||
windowTitle: 'Documents',
|
||||
cpuUsage: 0.8,
|
||||
},
|
||||
{
|
||||
id: '5',
|
||||
name: 'Slack',
|
||||
icon: 'https://a.slack-edge.com/80588/marketing/img/icons/icon_slack_hash_colored.svg',
|
||||
pid: 9876,
|
||||
memory: '198.4 MB',
|
||||
status: '活跃',
|
||||
statusType: 'active',
|
||||
path: '/Applications/Slack.app',
|
||||
windowTitle: 'Slack - workspace',
|
||||
cpuUsage: 3.7,
|
||||
},
|
||||
])
|
||||
|
||||
// 选择应用
|
||||
const selectApp = (app: Application) => {
|
||||
selectedApp.value = app
|
||||
emit('app-selected', app)
|
||||
}
|
||||
|
||||
// 鼠标悬停事件
|
||||
const handleMouseEnter = () => {
|
||||
// 可以在这里添加额外的悬停逻辑
|
||||
}
|
||||
|
||||
const handleMouseLeave = () => {
|
||||
// 可以在这里添加额外的离开逻辑
|
||||
}
|
||||
|
||||
// 暴露方法给父组件
|
||||
defineExpose({
|
||||
clearSelection: () => {
|
||||
selectedApp.value = null
|
||||
emit('app-selected', null)
|
||||
},
|
||||
selectById: (id: string) => {
|
||||
const app = applications.value.find((a) => a.id === id)
|
||||
if (app) {
|
||||
selectApp(app)
|
||||
}
|
||||
},
|
||||
})
|
||||
|
||||
// Props
|
||||
const props = defineProps<{
|
||||
width: number
|
||||
data: {
|
||||
activeConnections: number
|
||||
processCount: number
|
||||
networkSpeed: string
|
||||
ruleCount: number
|
||||
}
|
||||
}>()
|
||||
|
||||
// Emits
|
||||
const emit = defineEmits<{
|
||||
action: [type: string]
|
||||
}>()
|
||||
// 模拟数据
|
||||
const data = {
|
||||
activeConnections: 247,
|
||||
processCount: 43,
|
||||
networkSpeed: '5.2 MB/s',
|
||||
ruleCount: 156,
|
||||
}
|
||||
|
||||
// 处理快速操作
|
||||
const handleAction = (type: string) => {
|
||||
@@ -89,10 +210,401 @@ const handleAction = (type: string) => {
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
/* 书角折叠效果 - 平衡版 */
|
||||
.folded-corner {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: 0;
|
||||
width: 0;
|
||||
height: 0;
|
||||
border-left: 30px solid transparent;
|
||||
border-top: 30px solid var(--accent-primary);
|
||||
z-index: 10;
|
||||
animation: foldIn 0.3s ease-out;
|
||||
filter: drop-shadow(1px 1px 3px rgba(0, 0, 0, 0.15));
|
||||
}
|
||||
|
||||
.folded-corner::before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
top: -30px;
|
||||
right: -30px;
|
||||
width: 0;
|
||||
height: 0;
|
||||
border-left: 30px solid var(--accent-primary);
|
||||
border-top: 30px solid transparent;
|
||||
transform: rotate(90deg);
|
||||
transform-origin: 0 0;
|
||||
filter: brightness(0.85);
|
||||
}
|
||||
|
||||
.folded-corner::after {
|
||||
content: '';
|
||||
position: absolute;
|
||||
top: -22px;
|
||||
right: -22px;
|
||||
width: 0;
|
||||
height: 0;
|
||||
border-left: 22px solid rgba(0, 0, 0, 0.12);
|
||||
border-top: 22px solid transparent;
|
||||
transform: rotate(45deg);
|
||||
transform-origin: 0 0;
|
||||
}
|
||||
|
||||
/* 书角的轻微发光效果 */
|
||||
.app-item--selected .folded-corner {
|
||||
animation:
|
||||
foldIn 0.3s ease-out,
|
||||
cornerGlow 4s ease-in-out infinite alternate;
|
||||
}
|
||||
|
||||
@keyframes foldIn {
|
||||
0% {
|
||||
transform: scale(0.7) rotate(-15deg);
|
||||
opacity: 0;
|
||||
}
|
||||
60% {
|
||||
transform: scale(1.05) rotate(-3deg);
|
||||
opacity: 0.9;
|
||||
}
|
||||
100% {
|
||||
transform: scale(1) rotate(0deg);
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes cornerGlow {
|
||||
0% {
|
||||
filter: drop-shadow(1px 1px 3px rgba(0, 0, 0, 0.15));
|
||||
}
|
||||
100% {
|
||||
filter: drop-shadow(1px 1px 3px rgba(0, 0, 0, 0.15))
|
||||
drop-shadow(0 0 8px rgba(59, 130, 246, 0.4));
|
||||
}
|
||||
}
|
||||
|
||||
.app-list-view {
|
||||
height: 100%;
|
||||
background: var(--bg-secondary);
|
||||
}
|
||||
|
||||
.app-list-container {
|
||||
padding: 20px;
|
||||
max-width: 800px;
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
/* 头部 */
|
||||
.list-header {
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
.list-title {
|
||||
font-size: 18px;
|
||||
font-weight: 600;
|
||||
color: var(--text-primary);
|
||||
margin: 0 0 4px 0;
|
||||
}
|
||||
|
||||
.list-subtitle {
|
||||
font-size: 14px;
|
||||
color: var(--text-muted);
|
||||
}
|
||||
|
||||
/* 应用列表 */
|
||||
.app-list {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 8px;
|
||||
}
|
||||
|
||||
.app-item {
|
||||
background: var(--bg-card);
|
||||
backdrop-filter: var(--backdrop-blur);
|
||||
border: 1px solid var(--border-primary);
|
||||
border-radius: 12px;
|
||||
padding: 16px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 16px;
|
||||
cursor: pointer;
|
||||
transition: all 0.2s ease;
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.app-item:hover {
|
||||
transform: translateY(-1px);
|
||||
border-color: var(--border-hover);
|
||||
background: var(--bg-hover, var(--bg-card));
|
||||
box-shadow: var(--shadow-md);
|
||||
}
|
||||
|
||||
.app-item--selected {
|
||||
border: 1px solid var(--accent-primary);
|
||||
background: var(--monitor-bg-card-selected);
|
||||
box-shadow:
|
||||
0 0 0 4px var(--monitor-accent-primary-alpha),
|
||||
0 8px 25px -5px rgba(59, 130, 246, 0.3);
|
||||
transform: translateY(-1px) scale(1.02);
|
||||
position: relative;
|
||||
z-index: 5;
|
||||
}
|
||||
|
||||
/* 选中元素的左侧强调边框 */
|
||||
.app-item--selected::before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
left: -2px;
|
||||
top: -2px;
|
||||
bottom: -2px;
|
||||
width: 6px;
|
||||
background: linear-gradient(
|
||||
to bottom,
|
||||
var(--accent-primary) 0%,
|
||||
#1d4ed8 50%,
|
||||
var(--accent-primary) 100%
|
||||
);
|
||||
border-radius: 6px 0 0 6px;
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
/* 应用图标 */
|
||||
.app-icon {
|
||||
width: 48px;
|
||||
height: 48px;
|
||||
border-radius: 10px;
|
||||
overflow: hidden;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
background: var(--bg-tertiary);
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.app-icon img {
|
||||
width: 32px;
|
||||
height: 32px;
|
||||
object-fit: contain;
|
||||
}
|
||||
|
||||
/* 应用信息 */
|
||||
.app-info {
|
||||
flex: 1;
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
.app-name {
|
||||
font-size: 15px;
|
||||
font-weight: 600;
|
||||
color: var(--text-primary);
|
||||
margin-bottom: 4px;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
|
||||
.app-details {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 12px;
|
||||
font-size: 12px;
|
||||
color: var(--text-muted);
|
||||
}
|
||||
|
||||
.app-detail {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 4px;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
/* 状态指示器 */
|
||||
.app-status {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.status-indicator {
|
||||
width: 8px;
|
||||
height: 8px;
|
||||
border-radius: 50%;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.status-indicator::before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
top: -2px;
|
||||
left: -2px;
|
||||
right: -2px;
|
||||
bottom: -2px;
|
||||
border-radius: 50%;
|
||||
opacity: 0.3;
|
||||
animation: pulse 2s infinite;
|
||||
}
|
||||
|
||||
.status-active {
|
||||
background: var(--accent-success);
|
||||
}
|
||||
|
||||
.status-active::before {
|
||||
background: var(--accent-success);
|
||||
}
|
||||
|
||||
.status-background {
|
||||
background: var(--accent-warning);
|
||||
}
|
||||
|
||||
.status-background::before {
|
||||
background: var(--accent-warning);
|
||||
}
|
||||
|
||||
.status-idle {
|
||||
background: var(--text-quaternary);
|
||||
}
|
||||
|
||||
.status-idle::before {
|
||||
background: var(--text-quaternary);
|
||||
}
|
||||
|
||||
/* 空状态 */
|
||||
.empty-state {
|
||||
text-align: center;
|
||||
padding: 60px 20px;
|
||||
}
|
||||
|
||||
.empty-icon {
|
||||
color: var(--text-quaternary);
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
|
||||
.empty-title {
|
||||
font-size: 16px;
|
||||
font-weight: 600;
|
||||
color: var(--text-secondary);
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
|
||||
.empty-subtitle {
|
||||
font-size: 14px;
|
||||
color: var(--text-muted);
|
||||
}
|
||||
|
||||
/* 动画 */
|
||||
@keyframes pulse {
|
||||
0%,
|
||||
100% {
|
||||
opacity: 0.3;
|
||||
transform: scale(1);
|
||||
}
|
||||
50% {
|
||||
opacity: 0.8;
|
||||
transform: scale(1.2);
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes bounceIn {
|
||||
0% {
|
||||
opacity: 0;
|
||||
transform: scale(0.3);
|
||||
}
|
||||
50% {
|
||||
transform: scale(1.1);
|
||||
}
|
||||
100% {
|
||||
opacity: 1;
|
||||
transform: scale(1);
|
||||
}
|
||||
}
|
||||
|
||||
/* 响应式 */
|
||||
@media (max-width: 768px) {
|
||||
.app-item {
|
||||
padding: 12px;
|
||||
}
|
||||
|
||||
.app-icon {
|
||||
width: 40px;
|
||||
height: 40px;
|
||||
}
|
||||
|
||||
.app-icon img {
|
||||
width: 28px;
|
||||
height: 28px;
|
||||
}
|
||||
|
||||
.app-details {
|
||||
flex-direction: column;
|
||||
align-items: flex-start;
|
||||
gap: 4px;
|
||||
}
|
||||
|
||||
.folded-corner {
|
||||
border-left-width: 24px;
|
||||
border-top-width: 24px;
|
||||
}
|
||||
|
||||
.folded-corner::before {
|
||||
border-left-width: 24px;
|
||||
border-top-width: 24px;
|
||||
top: -24px;
|
||||
right: -24px;
|
||||
}
|
||||
|
||||
.folded-corner::after {
|
||||
border-left-width: 18px;
|
||||
border-top-width: 18px;
|
||||
top: -18px;
|
||||
right: -18px;
|
||||
}
|
||||
}
|
||||
|
||||
/* CSS变量定义 */
|
||||
:root {
|
||||
--monitor-bg-card-selected: rgba(59, 130, 246, 0.08);
|
||||
--monitor-accent-primary-alpha: rgba(59, 130, 246, 0.2);
|
||||
--accent-primary: #3b82f6;
|
||||
--accent-success: #10b981;
|
||||
--accent-warning: #f59e0b;
|
||||
--bg-card: #ffffff;
|
||||
--bg-hover: #f8fafc;
|
||||
--bg-tertiary: #f8fafc;
|
||||
--border-primary: #e2e8f0;
|
||||
--border-hover: #cbd5e1;
|
||||
--text-primary: #1e293b;
|
||||
--text-secondary: #475569;
|
||||
--text-muted: #64748b;
|
||||
--text-quaternary: #94a3b8;
|
||||
--shadow-lg: 0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -2px rgba(0, 0, 0, 0.05);
|
||||
--shadow-md: 0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06);
|
||||
}
|
||||
|
||||
/* 深色模式适配 */
|
||||
@media (prefers-color-scheme: dark) {
|
||||
:root {
|
||||
--monitor-bg-card-selected: rgba(59, 130, 246, 0.12);
|
||||
--monitor-accent-primary-alpha: rgba(59, 130, 246, 0.25);
|
||||
--bg-card: #1e293b;
|
||||
--bg-hover: #334155;
|
||||
--bg-tertiary: #334155;
|
||||
--border-primary: #475569;
|
||||
--border-hover: #64748b;
|
||||
--text-primary: #f1f5f9;
|
||||
--text-secondary: #e2e8f0;
|
||||
--text-muted: #cbd5e1;
|
||||
--text-quaternary: #94a3b8;
|
||||
}
|
||||
|
||||
.folded-corner::after {
|
||||
border-left-color: rgba(255, 255, 255, 0.08);
|
||||
}
|
||||
}
|
||||
|
||||
/* 侧边栏容器 */
|
||||
.sidebar {
|
||||
background: var(--bg-glass);
|
||||
backdrop-filter: var(--backdrop-blur);
|
||||
background: var(--bg-glass, var(--bg-card));
|
||||
backdrop-filter: var(--backdrop-blur, blur(10px));
|
||||
border-right: 1px solid var(--border-primary);
|
||||
overflow: hidden;
|
||||
display: flex;
|
||||
@@ -138,114 +650,4 @@ const handleAction = (type: string) => {
|
||||
gap: 12px;
|
||||
margin-bottom: 24px;
|
||||
}
|
||||
|
||||
.stat-card {
|
||||
background: var(--bg-card);
|
||||
border: 1px solid var(--border-tertiary);
|
||||
border-radius: 12px;
|
||||
padding: 16px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 12px;
|
||||
transition: var(--transition);
|
||||
}
|
||||
|
||||
.stat-card:hover {
|
||||
background: var(--bg-hover);
|
||||
border-color: var(--border-hover);
|
||||
transform: translateY(-1px);
|
||||
}
|
||||
|
||||
.stat-icon {
|
||||
font-size: 20px;
|
||||
width: 32px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.stat-info {
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.stat-value {
|
||||
font-size: 18px;
|
||||
font-weight: 700;
|
||||
color: var(--text-secondary);
|
||||
line-height: 1;
|
||||
}
|
||||
|
||||
.stat-label {
|
||||
font-size: 12px;
|
||||
color: var(--text-muted);
|
||||
margin-top: 2px;
|
||||
}
|
||||
|
||||
/* 侧边栏区块 */
|
||||
.sidebar-section {
|
||||
margin-top: 24px;
|
||||
}
|
||||
|
||||
.section-title {
|
||||
font-size: 14px;
|
||||
font-weight: 600;
|
||||
color: var(--text-quaternary);
|
||||
margin-bottom: 12px;
|
||||
}
|
||||
|
||||
/* 快速操作 */
|
||||
.quick-actions {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 8px;
|
||||
}
|
||||
|
||||
.action-item {
|
||||
padding: 8px 12px;
|
||||
background: var(--bg-tertiary);
|
||||
border-radius: 8px;
|
||||
font-size: 13px;
|
||||
color: var(--text-quaternary);
|
||||
cursor: pointer;
|
||||
transition: var(--transition);
|
||||
}
|
||||
|
||||
.action-item:hover {
|
||||
background: var(--bg-hover);
|
||||
color: var(--text-secondary);
|
||||
}
|
||||
|
||||
/* 系统状态 */
|
||||
.system-status {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 10px;
|
||||
}
|
||||
|
||||
.status-item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
font-size: 13px;
|
||||
color: var(--text-tertiary);
|
||||
}
|
||||
|
||||
.status-dot {
|
||||
width: 8px;
|
||||
height: 8px;
|
||||
border-radius: 50%;
|
||||
background: var(--text-disabled);
|
||||
}
|
||||
|
||||
.status-dot.active {
|
||||
background: var(--accent-success);
|
||||
box-shadow: 0 0 0 2px rgba(34, 197, 94, 0.2);
|
||||
}
|
||||
|
||||
.status-dot.warning {
|
||||
background: var(--accent-warning);
|
||||
box-shadow: 0 0 0 2px rgba(251, 146, 60, 0.2);
|
||||
}
|
||||
|
||||
.status-label {
|
||||
flex: 1;
|
||||
}
|
||||
</style>
|
||||
@@ -3,7 +3,7 @@
|
||||
<!-- 主内容区域 - 可拖拽布局 -->
|
||||
<div class="main-content">
|
||||
<!-- 左侧边栏 -->
|
||||
<MonitorSidebar :width="sidebarWidth" :data="mockData" />
|
||||
<MonitorSidebar :width="sidebarWidth" />
|
||||
|
||||
<!-- 左侧分割线 -->
|
||||
<div class="resize-handle-vertical" @mousedown="startResize('sidebar', $event)">
|
||||
@@ -49,7 +49,7 @@ import MonitorMainPanel from './MonitorMainPanel.vue'
|
||||
import MonitorInspector from './MonitorInspector.vue'
|
||||
|
||||
// 布局尺寸控制
|
||||
const sidebarWidth = ref(300)
|
||||
const sidebarWidth = ref(400)
|
||||
const inspectorWidth = ref(350)
|
||||
const timelineHeight = ref(500)
|
||||
const mainHeaderHeight = ref(80)
|
||||
@@ -66,14 +66,6 @@ const MAX_TIMELINE_HEIGHT = 800
|
||||
const searchQuery = ref('')
|
||||
const selectedConnection = ref<any>(null)
|
||||
|
||||
// 模拟数据
|
||||
const mockData = ref({
|
||||
activeConnections: 247,
|
||||
processCount: 43,
|
||||
networkSpeed: '5.2 MB/s',
|
||||
ruleCount: 156,
|
||||
})
|
||||
|
||||
const mockConnections = ref([
|
||||
{
|
||||
id: 1,
|
||||
|
||||
Reference in new issue
Block a user