实现 setting
419
app/package-lock.json
generated
@ -28,7 +28,9 @@
|
||||
"eslint-plugin-prettier": "^4.0.0",
|
||||
"eslint-plugin-vue": "^8.0.3",
|
||||
"prettier": "^2.4.1",
|
||||
"typescript": "~4.5.5"
|
||||
"typescript": "~4.5.5",
|
||||
"unplugin-auto-import": "^0.17.5",
|
||||
"unplugin-vue-components": "^0.26.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@achrinza/node-ipc": {
|
||||
@ -60,6 +62,16 @@
|
||||
"node": ">=6.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@antfu/utils": {
|
||||
"version": "0.7.10",
|
||||
"resolved": "https://registry.npmjs.org/@antfu/utils/-/utils-0.7.10.tgz",
|
||||
"integrity": "sha512-+562v9k4aI80m1+VuMHehNJWLOFjBnXn3tdOitzD0il5b7smkSBal4+a3oKiQTbrwMmN/TBUMDvbdoWDehgOww==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/antfu"
|
||||
}
|
||||
},
|
||||
"node_modules/@babel/code-frame": {
|
||||
"version": "7.26.2",
|
||||
"resolved": "https://registry.npmmirror.com/@babel/code-frame/-/code-frame-7.26.2.tgz",
|
||||
@ -2105,6 +2117,42 @@
|
||||
"url": "https://opencollective.com/popperjs"
|
||||
}
|
||||
},
|
||||
"node_modules/@rollup/pluginutils": {
|
||||
"version": "5.1.4",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-5.1.4.tgz",
|
||||
"integrity": "sha512-USm05zrsFxYLPdWWq+K3STlWiT/3ELn3RcV5hJMghpeAIhxfsUIg6mt12CBJBInWMV4VneoV7SfGv8xIwo2qNQ==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@types/estree": "^1.0.0",
|
||||
"estree-walker": "^2.0.2",
|
||||
"picomatch": "^4.0.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=14.0.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"rollup": "^1.20.0||^2.0.0||^3.0.0||^4.0.0"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"rollup": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/@rollup/pluginutils/node_modules/picomatch": {
|
||||
"version": "4.0.2",
|
||||
"resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.2.tgz",
|
||||
"integrity": "sha512-M7BAV6Rlcy5u+m6oPhAPFgJTzAioX/6B0DxyvDlo9l8+T3nLKbrczg2WLUyzd45L8RqfUMyGPzekbMvX2Ldkwg==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/jonschlinkert"
|
||||
}
|
||||
},
|
||||
"node_modules/@sideway/address": {
|
||||
"version": "4.1.5",
|
||||
"resolved": "https://registry.npmmirror.com/@sideway/address/-/address-4.1.5.tgz",
|
||||
@ -4802,6 +4850,13 @@
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/confbox": {
|
||||
"version": "0.1.8",
|
||||
"resolved": "https://registry.npmjs.org/confbox/-/confbox-0.1.8.tgz",
|
||||
"integrity": "sha512-RMtmw0iFkeR4YV+fUOSucriAQNb9g8zFR52MWCtl+cCZOFRNL6zeB395vPzFhEjjn4fMxXudmELnl/KF/WrK6w==",
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/connect-history-api-fallback": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmmirror.com/connect-history-api-fallback/-/connect-history-api-fallback-2.0.0.tgz",
|
||||
@ -6718,6 +6773,13 @@
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/exsolve": {
|
||||
"version": "1.0.4",
|
||||
"resolved": "https://registry.npmjs.org/exsolve/-/exsolve-1.0.4.tgz",
|
||||
"integrity": "sha512-xsZH6PXaER4XoV+NiT7JHp1bJodJVT+cxeSH1G0f0tlT0lJqYuHUP3bUx2HtfTDvOagMINYp8rsqusxud3RXhw==",
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/fast-deep-equal": {
|
||||
"version": "3.1.3",
|
||||
"resolved": "https://registry.npmmirror.com/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz",
|
||||
@ -8299,6 +8361,23 @@
|
||||
"json5": "lib/cli.js"
|
||||
}
|
||||
},
|
||||
"node_modules/local-pkg": {
|
||||
"version": "0.5.1",
|
||||
"resolved": "https://registry.npmjs.org/local-pkg/-/local-pkg-0.5.1.tgz",
|
||||
"integrity": "sha512-9rrA30MRRP3gBD3HTGnC6cDFpaE1kVDWxWgqWJUN0RvDNAo+Nz/9GxB+nHOH0ifbVFy0hSA1V6vFDvnx54lTEQ==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"mlly": "^1.7.3",
|
||||
"pkg-types": "^1.2.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=14"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/antfu"
|
||||
}
|
||||
},
|
||||
"node_modules/locate-path": {
|
||||
"version": "5.0.0",
|
||||
"resolved": "https://registry.npmmirror.com/locate-path/-/locate-path-5.0.0.tgz",
|
||||
@ -8887,6 +8966,19 @@
|
||||
"dev": true,
|
||||
"license": "ISC"
|
||||
},
|
||||
"node_modules/mlly": {
|
||||
"version": "1.7.4",
|
||||
"resolved": "https://registry.npmjs.org/mlly/-/mlly-1.7.4.tgz",
|
||||
"integrity": "sha512-qmdSIPC4bDJXgZTCR7XosJiNKySV7O215tsPtDN9iEO/7q/76b/ijtgRu/+epFXSJhijtTCCGp3DWS549P3xKw==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"acorn": "^8.14.0",
|
||||
"pathe": "^2.0.1",
|
||||
"pkg-types": "^1.3.0",
|
||||
"ufo": "^1.5.4"
|
||||
}
|
||||
},
|
||||
"node_modules/module-alias": {
|
||||
"version": "2.2.3",
|
||||
"resolved": "https://registry.npmmirror.com/module-alias/-/module-alias-2.2.3.tgz",
|
||||
@ -9532,6 +9624,13 @@
|
||||
"node": ">=8"
|
||||
}
|
||||
},
|
||||
"node_modules/pathe": {
|
||||
"version": "2.0.3",
|
||||
"resolved": "https://registry.npmjs.org/pathe/-/pathe-2.0.3.tgz",
|
||||
"integrity": "sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==",
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/picocolors": {
|
||||
"version": "1.1.1",
|
||||
"resolved": "https://registry.npmmirror.com/picocolors/-/picocolors-1.1.1.tgz",
|
||||
@ -9564,6 +9663,18 @@
|
||||
"node": ">=8"
|
||||
}
|
||||
},
|
||||
"node_modules/pkg-types": {
|
||||
"version": "1.3.1",
|
||||
"resolved": "https://registry.npmjs.org/pkg-types/-/pkg-types-1.3.1.tgz",
|
||||
"integrity": "sha512-/Jm5M4RvtBFVkKWRu2BLUTNP8/M2a+UwuAX+ae4770q1qVGtfjG+WTCupoZixokjmHiry8uI+dlY8KXYV5HVVQ==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"confbox": "^0.1.8",
|
||||
"mlly": "^1.7.4",
|
||||
"pathe": "^2.0.1"
|
||||
}
|
||||
},
|
||||
"node_modules/portfinder": {
|
||||
"version": "1.0.35",
|
||||
"resolved": "https://registry.npmmirror.com/portfinder/-/portfinder-1.0.35.tgz",
|
||||
@ -10424,6 +10535,23 @@
|
||||
"url": "https://github.com/sponsors/ljharb"
|
||||
}
|
||||
},
|
||||
"node_modules/quansync": {
|
||||
"version": "0.2.10",
|
||||
"resolved": "https://registry.npmjs.org/quansync/-/quansync-0.2.10.tgz",
|
||||
"integrity": "sha512-t41VRkMYbkHyCYmOvx/6URnN80H7k4X0lLdBMGsz+maAwrJQYB1djpV6vHrQIBE0WBSGqhtEHrK9U3DWWH8v7A==",
|
||||
"dev": true,
|
||||
"funding": [
|
||||
{
|
||||
"type": "individual",
|
||||
"url": "https://github.com/sponsors/antfu"
|
||||
},
|
||||
{
|
||||
"type": "individual",
|
||||
"url": "https://github.com/sponsors/sxzz"
|
||||
}
|
||||
],
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/queue-microtask": {
|
||||
"version": "1.2.3",
|
||||
"resolved": "https://registry.npmmirror.com/queue-microtask/-/queue-microtask-1.2.3.tgz",
|
||||
@ -10859,6 +10987,13 @@
|
||||
"url": "https://opencollective.com/webpack"
|
||||
}
|
||||
},
|
||||
"node_modules/scule": {
|
||||
"version": "1.3.0",
|
||||
"resolved": "https://registry.npmjs.org/scule/-/scule-1.3.0.tgz",
|
||||
"integrity": "sha512-6FtHJEvt+pVMIB9IBY+IcCJ6Z5f1iQnytgyfKMhDKgmzYG+TeH/wx1y3l27rshSbLiSanrR9ffZDrEsmjlQF2g==",
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/select-hose": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmmirror.com/select-hose/-/select-hose-2.0.0.tgz",
|
||||
@ -11490,6 +11625,26 @@
|
||||
"url": "https://github.com/sponsors/sindresorhus"
|
||||
}
|
||||
},
|
||||
"node_modules/strip-literal": {
|
||||
"version": "2.1.1",
|
||||
"resolved": "https://registry.npmjs.org/strip-literal/-/strip-literal-2.1.1.tgz",
|
||||
"integrity": "sha512-631UJ6O00eNGfMiWG78ck80dfBab8X6IVFB51jZK5Icd7XAs60Z5y7QdSd/wGIklnWvRbUNloVzhOKKmutxQ6Q==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"js-tokens": "^9.0.1"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/antfu"
|
||||
}
|
||||
},
|
||||
"node_modules/strip-literal/node_modules/js-tokens": {
|
||||
"version": "9.0.1",
|
||||
"resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-9.0.1.tgz",
|
||||
"integrity": "sha512-mxa9E9ITFOt0ban3j6L5MpjwegGz6lBQmM1IJkWeBZGcMxto50+eWdjC/52xDbS2vy0k7vIMK0Fe2wfL9OQSpQ==",
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/stylehacks": {
|
||||
"version": "5.1.1",
|
||||
"resolved": "https://registry.npmmirror.com/stylehacks/-/stylehacks-5.1.1.tgz",
|
||||
@ -12017,6 +12172,13 @@
|
||||
"node": ">=4.2.0"
|
||||
}
|
||||
},
|
||||
"node_modules/ufo": {
|
||||
"version": "1.5.4",
|
||||
"resolved": "https://registry.npmjs.org/ufo/-/ufo-1.5.4.tgz",
|
||||
"integrity": "sha512-UsUk3byDzKd04EyoZ7U4DOlxQaD14JUKQl6/P7wiX4FNvUfm3XL246n9W5AmqwW5RSFJ27NAuM0iLscAOYUiGQ==",
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/undici-types": {
|
||||
"version": "6.20.0",
|
||||
"resolved": "https://registry.npmmirror.com/undici-types/-/undici-types-6.20.0.tgz",
|
||||
@ -12068,6 +12230,102 @@
|
||||
"node": ">=4"
|
||||
}
|
||||
},
|
||||
"node_modules/unimport": {
|
||||
"version": "3.14.6",
|
||||
"resolved": "https://registry.npmjs.org/unimport/-/unimport-3.14.6.tgz",
|
||||
"integrity": "sha512-CYvbDaTT04Rh8bmD8jz3WPmHYZRG/NnvYVzwD6V1YAlvvKROlAeNDUBhkBGzNav2RKaeuXvlWYaa1V4Lfi/O0g==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@rollup/pluginutils": "^5.1.4",
|
||||
"acorn": "^8.14.0",
|
||||
"escape-string-regexp": "^5.0.0",
|
||||
"estree-walker": "^3.0.3",
|
||||
"fast-glob": "^3.3.3",
|
||||
"local-pkg": "^1.0.0",
|
||||
"magic-string": "^0.30.17",
|
||||
"mlly": "^1.7.4",
|
||||
"pathe": "^2.0.1",
|
||||
"picomatch": "^4.0.2",
|
||||
"pkg-types": "^1.3.0",
|
||||
"scule": "^1.3.0",
|
||||
"strip-literal": "^2.1.1",
|
||||
"unplugin": "^1.16.1"
|
||||
}
|
||||
},
|
||||
"node_modules/unimport/node_modules/confbox": {
|
||||
"version": "0.2.1",
|
||||
"resolved": "https://registry.npmjs.org/confbox/-/confbox-0.2.1.tgz",
|
||||
"integrity": "sha512-hkT3yDPFbs95mNCy1+7qNKC6Pro+/ibzYxtM2iqEigpf0sVw+bg4Zh9/snjsBcf990vfIsg5+1U7VyiyBb3etg==",
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/unimport/node_modules/escape-string-regexp": {
|
||||
"version": "5.0.0",
|
||||
"resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-5.0.0.tgz",
|
||||
"integrity": "sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/sindresorhus"
|
||||
}
|
||||
},
|
||||
"node_modules/unimport/node_modules/estree-walker": {
|
||||
"version": "3.0.3",
|
||||
"resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-3.0.3.tgz",
|
||||
"integrity": "sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@types/estree": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/unimport/node_modules/local-pkg": {
|
||||
"version": "1.1.1",
|
||||
"resolved": "https://registry.npmjs.org/local-pkg/-/local-pkg-1.1.1.tgz",
|
||||
"integrity": "sha512-WunYko2W1NcdfAFpuLUoucsgULmgDBRkdxHxWQ7mK0cQqwPiy8E1enjuRBrhLtZkB5iScJ1XIPdhVEFK8aOLSg==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"mlly": "^1.7.4",
|
||||
"pkg-types": "^2.0.1",
|
||||
"quansync": "^0.2.8"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=14"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/antfu"
|
||||
}
|
||||
},
|
||||
"node_modules/unimport/node_modules/local-pkg/node_modules/pkg-types": {
|
||||
"version": "2.1.0",
|
||||
"resolved": "https://registry.npmjs.org/pkg-types/-/pkg-types-2.1.0.tgz",
|
||||
"integrity": "sha512-wmJwA+8ihJixSoHKxZJRBQG1oY8Yr9pGLzRmSsNms0iNWyHHAlZCa7mmKiFR10YPZuz/2k169JiS/inOjBCZ2A==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"confbox": "^0.2.1",
|
||||
"exsolve": "^1.0.1",
|
||||
"pathe": "^2.0.3"
|
||||
}
|
||||
},
|
||||
"node_modules/unimport/node_modules/picomatch": {
|
||||
"version": "4.0.2",
|
||||
"resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.2.tgz",
|
||||
"integrity": "sha512-M7BAV6Rlcy5u+m6oPhAPFgJTzAioX/6B0DxyvDlo9l8+T3nLKbrczg2WLUyzd45L8RqfUMyGPzekbMvX2Ldkwg==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/jonschlinkert"
|
||||
}
|
||||
},
|
||||
"node_modules/universalify": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmmirror.com/universalify/-/universalify-2.0.1.tgz",
|
||||
@ -12088,6 +12346,165 @@
|
||||
"node": ">= 0.8"
|
||||
}
|
||||
},
|
||||
"node_modules/unplugin": {
|
||||
"version": "1.16.1",
|
||||
"resolved": "https://registry.npmjs.org/unplugin/-/unplugin-1.16.1.tgz",
|
||||
"integrity": "sha512-4/u/j4FrCKdi17jaxuJA0jClGxB1AvU2hw/IuayPc4ay1XGaJs/rbb4v5WKwAjNifjmXK9PIFyuPiaK8azyR9w==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"acorn": "^8.14.0",
|
||||
"webpack-virtual-modules": "^0.6.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=14.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/unplugin-auto-import": {
|
||||
"version": "0.17.8",
|
||||
"resolved": "https://registry.npmjs.org/unplugin-auto-import/-/unplugin-auto-import-0.17.8.tgz",
|
||||
"integrity": "sha512-CHryj6HzJ+n4ASjzwHruD8arhbdl+UXvhuAIlHDs15Y/IMecG3wrf7FVg4pVH/DIysbq/n0phIjNHAjl7TG7Iw==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@antfu/utils": "^0.7.10",
|
||||
"@rollup/pluginutils": "^5.1.0",
|
||||
"fast-glob": "^3.3.2",
|
||||
"local-pkg": "^0.5.0",
|
||||
"magic-string": "^0.30.10",
|
||||
"minimatch": "^9.0.4",
|
||||
"unimport": "^3.7.2",
|
||||
"unplugin": "^1.11.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=14"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/antfu"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@nuxt/kit": "^3.2.2",
|
||||
"@vueuse/core": "*"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"@nuxt/kit": {
|
||||
"optional": true
|
||||
},
|
||||
"@vueuse/core": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/unplugin-auto-import/node_modules/brace-expansion": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz",
|
||||
"integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"balanced-match": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/unplugin-auto-import/node_modules/minimatch": {
|
||||
"version": "9.0.5",
|
||||
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz",
|
||||
"integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==",
|
||||
"dev": true,
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"brace-expansion": "^2.0.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=16 || 14 >=14.17"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/isaacs"
|
||||
}
|
||||
},
|
||||
"node_modules/unplugin-vue-components": {
|
||||
"version": "0.26.0",
|
||||
"resolved": "https://registry.npmjs.org/unplugin-vue-components/-/unplugin-vue-components-0.26.0.tgz",
|
||||
"integrity": "sha512-s7IdPDlnOvPamjunVxw8kNgKNK8A5KM1YpK5j/p97jEKTjlPNrA0nZBiSfAKKlK1gWZuyWXlKL5dk3EDw874LQ==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@antfu/utils": "^0.7.6",
|
||||
"@rollup/pluginutils": "^5.0.4",
|
||||
"chokidar": "^3.5.3",
|
||||
"debug": "^4.3.4",
|
||||
"fast-glob": "^3.3.1",
|
||||
"local-pkg": "^0.4.3",
|
||||
"magic-string": "^0.30.3",
|
||||
"minimatch": "^9.0.3",
|
||||
"resolve": "^1.22.4",
|
||||
"unplugin": "^1.4.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=14"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/antfu"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@babel/parser": "^7.15.8",
|
||||
"@nuxt/kit": "^3.2.2",
|
||||
"vue": "2 || 3"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"@babel/parser": {
|
||||
"optional": true
|
||||
},
|
||||
"@nuxt/kit": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/unplugin-vue-components/node_modules/brace-expansion": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz",
|
||||
"integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"balanced-match": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/unplugin-vue-components/node_modules/local-pkg": {
|
||||
"version": "0.4.3",
|
||||
"resolved": "https://registry.npmjs.org/local-pkg/-/local-pkg-0.4.3.tgz",
|
||||
"integrity": "sha512-SFppqq5p42fe2qcZQqqEOiVRXl+WCP1MdT6k7BDEW1j++sp5fIY+/fdRQitvKgB5BrBcmrs5m/L0v2FrU5MY1g==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=14"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/antfu"
|
||||
}
|
||||
},
|
||||
"node_modules/unplugin-vue-components/node_modules/minimatch": {
|
||||
"version": "9.0.5",
|
||||
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz",
|
||||
"integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==",
|
||||
"dev": true,
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"brace-expansion": "^2.0.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=16 || 14 >=14.17"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/isaacs"
|
||||
}
|
||||
},
|
||||
"node_modules/unplugin/node_modules/webpack-virtual-modules": {
|
||||
"version": "0.6.2",
|
||||
"resolved": "https://registry.npmjs.org/webpack-virtual-modules/-/webpack-virtual-modules-0.6.2.tgz",
|
||||
"integrity": "sha512-66/V2i5hQanC51vBQKPH4aI8NMAcBW59FVBs+rC7eGHupMyfn34q7rZIE+ETlJ+XTevqfUhVVBgSUNSW2flEUQ==",
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/update-browserslist-db": {
|
||||
"version": "1.1.3",
|
||||
"resolved": "https://registry.npmmirror.com/update-browserslist-db/-/update-browserslist-db-1.1.3.tgz",
|
||||
|
@ -28,6 +28,8 @@
|
||||
"eslint-plugin-prettier": "^4.0.0",
|
||||
"eslint-plugin-vue": "^8.0.3",
|
||||
"prettier": "^2.4.1",
|
||||
"typescript": "~4.5.5"
|
||||
"typescript": "~4.5.5",
|
||||
"unplugin-auto-import": "^0.17.5",
|
||||
"unplugin-vue-components": "^0.26.0"
|
||||
}
|
||||
}
|
||||
|
Before Width: | Height: | Size: 4.2 KiB |
Before Width: | Height: | Size: 1.7 KiB After Width: | Height: | Size: 1.7 KiB |
@ -1,8 +1,8 @@
|
||||
@font-face {
|
||||
font-family: "iconfont"; /* Project id 4870215 */
|
||||
src: url('iconfont.woff2?t=1742911403305') format('woff2'),
|
||||
url('iconfont.woff?t=1742911403305') format('woff'),
|
||||
url('iconfont.ttf?t=1742911403305') format('truetype');
|
||||
src: url('iconfont.woff2?t=1742978562991') format('woff2'),
|
||||
url('iconfont.woff?t=1742978562991') format('woff'),
|
||||
url('iconfont.ttf?t=1742978562991') format('truetype');
|
||||
}
|
||||
|
||||
.iconfont {
|
||||
@ -13,6 +13,38 @@
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
}
|
||||
|
||||
.icon-company:before {
|
||||
content: "\e6f5";
|
||||
}
|
||||
|
||||
.icon-token:before {
|
||||
content: "\e68f";
|
||||
}
|
||||
|
||||
.icon-url-line:before {
|
||||
content: "\ea38";
|
||||
}
|
||||
|
||||
.icon-llm:before {
|
||||
content: "\e8be";
|
||||
}
|
||||
|
||||
.icon-bg-colors:before {
|
||||
content: "\e800";
|
||||
}
|
||||
|
||||
.icon-i18n:before {
|
||||
content: "\e601";
|
||||
}
|
||||
|
||||
.icon-weixin:before {
|
||||
content: "\e600";
|
||||
}
|
||||
|
||||
.icon-QQ:before {
|
||||
content: "\e882";
|
||||
}
|
||||
|
||||
.icon-debug:before {
|
||||
content: "\e76d";
|
||||
}
|
||||
|
BIN
app/public/images/deepseek.com.ico
Normal file
After Width: | Height: | Size: 205 KiB |
BIN
app/public/images/grok.com.png
Normal file
After Width: | Height: | Size: 432 B |
22
app/public/images/gstatic.com.svg
Normal file
@ -0,0 +1,22 @@
|
||||
<svg width="1080" height="1080" viewBox="0 0 1080 1080" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M515.09 725.824L472.006 824.503C455.444 862.434 402.954 862.434 386.393 824.503L343.308 725.824C304.966 638.006 235.953 568.104 149.868 529.892L31.2779 477.251C-6.42601 460.515 -6.42594 405.665 31.2779 388.929L146.164 337.932C234.463 298.737 304.714 226.244 342.401 135.431L386.044 30.2693C402.239 -8.75637 456.159 -8.75646 472.355 30.2692L515.998 135.432C553.685 226.244 623.935 298.737 712.234 337.932L827.121 388.929C864.825 405.665 864.825 460.515 827.121 477.251L708.53 529.892C622.446 568.104 553.433 638.006 515.09 725.824Z" fill="url(#paint0_radial_2525_777)"/>
|
||||
<path d="M915.485 1036.98L903.367 1064.75C894.499 1085.08 866.349 1085.08 857.481 1064.75L845.364 1036.98C823.765 987.465 784.862 948.042 736.318 926.475L698.987 909.889C678.802 900.921 678.802 871.578 698.987 862.61L734.231 846.951C784.023 824.829 823.623 783.947 844.851 732.75L857.294 702.741C865.966 681.826 894.882 681.826 903.554 702.741L915.997 732.75C937.225 783.947 976.826 824.829 1026.62 846.951L1061.86 862.61C1082.05 871.578 1082.05 900.921 1061.86 909.889L1024.53 926.475C975.987 948.042 937.083 987.465 915.485 1036.98Z" fill="url(#paint1_radial_2525_777)"/>
|
||||
<defs>
|
||||
<radialGradient id="paint0_radial_2525_777" cx="0" cy="0" r="1" gradientUnits="userSpaceOnUse" gradientTransform="translate(670.447 474.006) rotate(78.858) scale(665.5 665.824)">
|
||||
<stop stop-color="#1BA1E3"/>
|
||||
<stop offset="0.0001" stop-color="#1BA1E3"/>
|
||||
<stop offset="0.300221" stop-color="#5489D6"/>
|
||||
<stop offset="0.545524" stop-color="#9B72CB"/>
|
||||
<stop offset="0.825372" stop-color="#D96570"/>
|
||||
<stop offset="1" stop-color="#F49C46"/>
|
||||
</radialGradient>
|
||||
<radialGradient id="paint1_radial_2525_777" cx="0" cy="0" r="1" gradientUnits="userSpaceOnUse" gradientTransform="translate(670.447 474.006) rotate(78.858) scale(665.5 665.824)">
|
||||
<stop stop-color="#1BA1E3"/>
|
||||
<stop offset="0.0001" stop-color="#1BA1E3"/>
|
||||
<stop offset="0.300221" stop-color="#5489D6"/>
|
||||
<stop offset="0.545524" stop-color="#9B72CB"/>
|
||||
<stop offset="0.825372" stop-color="#D96570"/>
|
||||
<stop offset="1" stop-color="#F49C46"/>
|
||||
</radialGradient>
|
||||
</defs>
|
||||
</svg>
|
After Width: | Height: | Size: 2.1 KiB |
BIN
app/public/images/kimichat.cn.png
Normal file
After Width: | Height: | Size: 1.4 KiB |
BIN
app/public/images/mistral.ai.ico
Normal file
After Width: | Height: | Size: 15 KiB |
BIN
app/public/images/ollama.png
Normal file
After Width: | Height: | Size: 498 B |
BIN
app/public/images/openai.com.ico
Normal file
After Width: | Height: | Size: 15 KiB |
BIN
app/public/images/openmcp-qq-qrcode.jpg
Normal file
After Width: | Height: | Size: 356 KiB |
20
app/public/images/openmcp.svg
Normal file
@ -0,0 +1,20 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<svg viewBox="0 0 824 834" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<defs>
|
||||
<path id="path_1" d="M300 0C465.708 0 600 134.292 600 300L600 300C600 465.708 465.708 600 300 600L300 600C134.292 600 0 465.708 0 300L0 300C0 134.292 134.292 0 300 0Z" />
|
||||
<linearGradient id="gradient_2" gradientUnits="userSpaceOnUse" x1="300" y1="0" x2="300" y2="600">
|
||||
<stop offset="0" stop-color="#A1A7F6" />
|
||||
<stop offset="1" stop-color="#FFFFFF" stop-opacity="0.2" />
|
||||
</linearGradient>
|
||||
</defs>
|
||||
<g>
|
||||
<g transform="translate(186 116)">
|
||||
<use p4:href="#path_1" fill="#5A00FF" xmlns:p4="http://www.w3.org/1999/xlink" />
|
||||
<use p4:href="#path_1" fill="url(#gradient_2)" xmlns:p4="http://www.w3.org/1999/xlink" />
|
||||
</g>
|
||||
<path d="M0 110.5C0 49.4725 49.4725 0 110.5 0C171.527 0 221 49.4725 221 110.5C221 171.527 171.527 221 110.5 221C49.4725 221 0 171.527 0 110.5Z" fill="#FFFFFF" fill-rule="evenodd" fill-opacity="0.431" transform="translate(445 458)" />
|
||||
<path d="M0 55.5C0 24.8482 24.8482 0 55.5 0C86.1518 0 111 24.8482 111 55.5C111 86.1518 86.1518 111 55.5 111C24.8482 111 0 86.1518 0 55.5Z" fill="#FFFFFF" fill-rule="evenodd" fill-opacity="0.431" transform="translate(199 386)" />
|
||||
<path d="M0 182.5C0 81.708 81.708 0 182.5 0C283.292 0 365 81.708 365 182.5C365 283.292 283.292 365 182.5 365C81.708 365 0 283.292 0 182.5Z" fill="#FFFFFF" fill-rule="evenodd" fill-opacity="0.424" transform="translate(339 156)" />
|
||||
<path d="M0 57C0 25.5198 25.5198 0 57 0C88.4802 0 114 25.5198 114 57C114 88.4802 88.4802 114 57 114C25.5198 114 0 88.4802 0 57Z" fill="#FFFFFF" fill-rule="evenodd" fill-opacity="0.431" transform="translate(521 188)" />
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 1.7 KiB |
BIN
app/public/images/perplexity.ai.ico
Normal file
After Width: | Height: | Size: 15 KiB |
@ -5,7 +5,7 @@
|
||||
<meta charset="utf-8">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<meta name="viewport" content="width=device-width,initial-scale=1.0">
|
||||
<link rel="icon" href="<%= BASE_URL %>favicon.ico">
|
||||
<link rel="icon" href="<%= BASE_URL %>favicon.svg">
|
||||
<link rel="stylesheet" href="default-dark.css">
|
||||
<link rel="stylesheet" href="vscode.css">
|
||||
<link rel="stylesheet" href="mcp.css">
|
||||
|
@ -11,12 +11,17 @@ import { Connection } from './components/sidebar/sidebar';
|
||||
|
||||
import Sidebar from '@/components/sidebar/index.vue';
|
||||
import MainPanel from '@/components/main-panel/index.vue';
|
||||
import { setDefaultCss } from './hook/css';
|
||||
import { pinkLog } from './views/setting/util';
|
||||
|
||||
|
||||
onMounted(() => {
|
||||
setDefaultCss();
|
||||
document.addEventListener('click', () => {
|
||||
Connection.showPanel = false;
|
||||
});
|
||||
|
||||
pinkLog('OpenMCP Client 启动');
|
||||
})
|
||||
|
||||
</script>
|
||||
|
@ -31,6 +31,7 @@ defineComponent({ name: 'main-panel' });
|
||||
justify-content: center;
|
||||
flex-direction: column;
|
||||
width: 100%;
|
||||
min-width: 800px;
|
||||
height: 100%;
|
||||
margin-left: 20px;
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
<template>
|
||||
<div class="mcp-title">
|
||||
<img src="/protocol.svg" alt="">
|
||||
<img src="/images/openmcp.svg" alt="">
|
||||
<div>OpenMCP</div>
|
||||
</div>
|
||||
</template>
|
||||
|
@ -8,13 +8,14 @@
|
||||
@click="gotoOption(item.ident)"
|
||||
>
|
||||
<span :class="`iconfont ${item.icon}`"></span>
|
||||
<span>{{ item.name }}</span>
|
||||
<span>{{ t(item.ident) }}</span>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { defineComponent } from 'vue';
|
||||
import { useI18n } from 'vue-i18n';
|
||||
import { useRoute, useRouter } from 'vue-router';
|
||||
import { sidebarItems } from './sidebar';
|
||||
|
||||
@ -22,6 +23,7 @@ defineComponent({ name: 'sidebar-item-container' });
|
||||
|
||||
const route = useRoute();
|
||||
const router = useRouter();
|
||||
const { t } = useI18n();
|
||||
|
||||
function isActive(name: string) {
|
||||
return route.name === name;
|
||||
|
@ -1,28 +1,20 @@
|
||||
import { reactive } from 'vue';
|
||||
|
||||
import I18n from '@/i18n';
|
||||
|
||||
const { t } = I18n.global;
|
||||
|
||||
export const sidebarItems = reactive([
|
||||
{
|
||||
icon: 'icon-debug',
|
||||
name: t('debug'),
|
||||
ident: 'debug'
|
||||
},
|
||||
{
|
||||
icon: 'icon-plugin',
|
||||
name: t('connect'),
|
||||
ident: 'connect'
|
||||
},
|
||||
{
|
||||
icon: 'icon-setting',
|
||||
name: t('setting'),
|
||||
ident: 'setting'
|
||||
},
|
||||
{
|
||||
icon: 'icon-about',
|
||||
name: t('about'),
|
||||
ident: 'about'
|
||||
}
|
||||
]);
|
||||
|
227
app/src/hook/color.ts
Normal file
@ -0,0 +1,227 @@
|
||||
interface RgbColor {
|
||||
r: number;
|
||||
g: number;
|
||||
b: number;
|
||||
a?: number; // 透明度,值介于 0 - 1 之间
|
||||
}
|
||||
|
||||
/**
|
||||
* @description 解析 rgb 字符串
|
||||
* @param colorString 形如 #1e90ff 或者 rgba(0, 206, 209, 1) 这样的字符串
|
||||
* @returns 解析后的 RgbColor 对象,如果解析失败则返回 undefined
|
||||
*/
|
||||
export function parseColor(colorString: string): RgbColor | undefined {
|
||||
// 检查是否是十六进制颜色
|
||||
if (colorString.startsWith('#')) {
|
||||
let hex = colorString.slice(1);
|
||||
if (hex.length === 3) {
|
||||
hex = hex.split('').map(c => c + c).join('');
|
||||
}
|
||||
const r = parseInt(hex.slice(0, 2), 16);
|
||||
const g = parseInt(hex.slice(2, 4), 16);
|
||||
const b = parseInt(hex.slice(4, 6), 16);
|
||||
return { r, g, b };
|
||||
}
|
||||
// 检查是否是 RGBA 颜色
|
||||
else if (colorString.startsWith('rgba')) {
|
||||
const matches = colorString.match(/rgba\((\d+),\s*(\d+),\s*(\d+),\s*(\d+(\.\d+)?)\)/);
|
||||
if (matches) {
|
||||
const r = parseInt(matches[1], 10);
|
||||
const g = parseInt(matches[2], 10);
|
||||
const b = parseInt(matches[3], 10);
|
||||
const a = parseFloat(matches[4]);
|
||||
return { r, g, b, a };
|
||||
}
|
||||
}
|
||||
// 检查是否是 RGB 颜色
|
||||
else if (colorString.startsWith('rgb')) {
|
||||
const matches = colorString.match(/rgb\((\d+),\s*(\d+),\s*(\d+)\)/);
|
||||
if (matches) {
|
||||
const r = parseInt(matches[1], 10);
|
||||
const g = parseInt(matches[2], 10);
|
||||
const b = parseInt(matches[3], 10);
|
||||
return { r, g, b };
|
||||
}
|
||||
}
|
||||
|
||||
return undefined;
|
||||
}
|
||||
|
||||
/**
|
||||
* @description 提升颜色的亮度
|
||||
* @param rgb 原始颜色对象
|
||||
* @param percent 0 - 100 的数字,代表增强的亮度比例
|
||||
* @returns 提升亮度后的 RgbColor 对象
|
||||
*/
|
||||
export function increaseBrightness(rgb: RgbColor, percent: number): RgbColor {
|
||||
// 确保 percent 在 0 到 100 之间
|
||||
percent = Math.max(0, Math.min(100, percent));
|
||||
|
||||
// 计算每个颜色分量的增量
|
||||
const increment = (percent / 100) * 255;
|
||||
|
||||
// 提升每个颜色分量的亮度
|
||||
const r = Math.min(255, Math.round(rgb.r + increment));
|
||||
const g = Math.min(255, Math.round(rgb.g + increment));
|
||||
const b = Math.min(255, Math.round(rgb.b + increment));
|
||||
|
||||
return { r, g, b };
|
||||
}
|
||||
|
||||
/**
|
||||
* @description 降低颜色的亮度
|
||||
* @param rgb 原始颜色对象
|
||||
* @param percent 0 - 100 的数字,代表降低的亮度比例
|
||||
* @returns 降低亮度后的 RgbColor 对象
|
||||
*/
|
||||
export function lowerBrightness(rgb: RgbColor, percent: number): RgbColor {
|
||||
// 确保 percent 在 0 到 100 之间
|
||||
percent = Math.max(0, Math.min(100, percent));
|
||||
|
||||
// 计算每个颜色分量的增量
|
||||
const increment = (percent / 100) * 255;
|
||||
|
||||
// 降低每个颜色分量的亮度
|
||||
const r = Math.max(0, Math.round(rgb.r - increment));
|
||||
const g = Math.max(0, Math.round(rgb.g - increment));
|
||||
const b = Math.max(0, Math.round(rgb.b - increment));
|
||||
|
||||
return { r, g, b };
|
||||
}
|
||||
|
||||
/**
|
||||
* @description gamma 修正
|
||||
* @param c 颜色通道值,取值范围为 0 - 255
|
||||
* @returns 修正后的值
|
||||
*/
|
||||
function gammaCorrected(c: number): number {
|
||||
c /= 255;
|
||||
return c <= 0.03928 ? c / 12.92 : Math.pow((c + 0.055) / 1.055, 2.4);
|
||||
}
|
||||
|
||||
/**
|
||||
* @description 判断是否为亮色主题
|
||||
* @param r 红色通道值
|
||||
* @param g 绿色通道值
|
||||
* @param b 蓝色通道值
|
||||
* @returns 如果是亮色主题则返回 true,否则返回 false
|
||||
*/
|
||||
export function isLightColorTheme(r: number, g: number, b: number): boolean {
|
||||
r = gammaCorrected(r);
|
||||
g = gammaCorrected(g);
|
||||
b = gammaCorrected(b);
|
||||
const luminance = 0.2126 * r + 0.7152 * g + 0.0722 * b;
|
||||
return luminance > 0.5;
|
||||
}
|
||||
|
||||
/**
|
||||
* @description 导出为 rgb css 样式的字符串
|
||||
* @param rgb 颜色对象
|
||||
* @returns RGB CSS 字符串
|
||||
*/
|
||||
export function toRgbCssString(rgb: RgbColor): string {
|
||||
const { r, g, b } = rgb;
|
||||
return `rgb(${r}, ${g}, ${b})`;
|
||||
}
|
||||
|
||||
/**
|
||||
* @description 导出为 rgba css 样式的字符串
|
||||
* @param rgb 颜色对象
|
||||
* @returns RGBA CSS 字符串
|
||||
*/
|
||||
export function toRgbaCssString(rgb: RgbColor): string {
|
||||
const { r, g, b, a } = rgb;
|
||||
return `rgba(${r}, ${g}, ${b}, ${a ?? 1})`;
|
||||
}
|
||||
|
||||
interface ComputedColorOption {
|
||||
BaseForegroundColorMacroName?: string;
|
||||
BaseBackgroundColorMacroName?: string;
|
||||
}
|
||||
|
||||
interface GetColorOption {
|
||||
mode?: 'pdf' | 'svg';
|
||||
}
|
||||
|
||||
export class MacroColor {
|
||||
private option: ComputedColorOption;
|
||||
private rootStyles: CSSStyleDeclaration;
|
||||
private theme: 'light' | 'dark';
|
||||
public foregroundColor: RgbColor | undefined;
|
||||
public backgroundColor: RgbColor | undefined;
|
||||
public foregroundColorString: string;
|
||||
public backgroundColorString: string;
|
||||
|
||||
constructor(option: ComputedColorOption = {}) {
|
||||
this.option = option;
|
||||
this.rootStyles = getComputedStyle(document.documentElement);
|
||||
|
||||
const foregroundColorString = this.rootStyles.getPropertyValue(option.BaseForegroundColorMacroName || '--foreground');
|
||||
const backgroundColorString = this.rootStyles.getPropertyValue(option.BaseBackgroundColorMacroName || '--background');
|
||||
this.foregroundColor = parseColor(foregroundColorString);
|
||||
this.backgroundColor = parseColor(backgroundColorString);
|
||||
|
||||
this.foregroundColorString = foregroundColorString;
|
||||
this.backgroundColorString = backgroundColorString;
|
||||
|
||||
if (this.backgroundColor) {
|
||||
const isLight = isLightColorTheme(this.backgroundColor.r, this.backgroundColor.g, this.backgroundColor.b);
|
||||
this.theme = isLight ? 'light' : 'dark';
|
||||
} else {
|
||||
this.theme = 'light'; // 默认主题
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @description 获取颜色值
|
||||
* @param macroName CSS 变量名
|
||||
* @param option 配置选项
|
||||
* @returns 颜色值字符串
|
||||
*/
|
||||
getColor(macroName: string, option: GetColorOption = {}): string {
|
||||
const theme = this.theme;
|
||||
const rootStyles = this.rootStyles;
|
||||
const mode = option.mode || 'svg';
|
||||
|
||||
if (mode === 'svg') {
|
||||
// svg 模式下,导出的效果和 webview 渲染效果基本一致,直接导出即可
|
||||
return rootStyles.getPropertyValue(macroName);
|
||||
}
|
||||
|
||||
// pdf 模式需要对黑色主题的几个特殊颜色进行处理,并对所有透明颜色进行混合处理
|
||||
switch (macroName) {
|
||||
case '--foreground':
|
||||
case '--wire-color':
|
||||
case '--cross-dot-color':
|
||||
if (theme === 'dark') {
|
||||
return '#2D323B';
|
||||
}
|
||||
}
|
||||
|
||||
const colorString = rootStyles.getPropertyValue(macroName);
|
||||
if (!colorString) {
|
||||
// 如果 macroName 不存在,返回空字符串
|
||||
return colorString;
|
||||
}
|
||||
|
||||
const color = parseColor(colorString);
|
||||
if (!color) {
|
||||
return colorString;
|
||||
}
|
||||
|
||||
if (!color.a) {
|
||||
// 不具有透明通道,在 pdf 中渲染效果和 svg 中一致,直接返回即可
|
||||
return toRgbCssString(color);
|
||||
}
|
||||
|
||||
// 透明度插值公式为 c = c_f * alpha + c_b * (1 - alpha)
|
||||
const mixedBg = parseColor('#ffffff')!; // 假设背景为白色
|
||||
const mixedColor = {
|
||||
r: Math.round(color.r * color.a + mixedBg.r * (1 - color.a)),
|
||||
g: Math.round(color.g * color.a + mixedBg.g * (1 - color.a)),
|
||||
b: Math.round(color.b * color.a + mixedBg.b * (1 - color.a)),
|
||||
};
|
||||
|
||||
return toRgbCssString(mixedColor);
|
||||
}
|
||||
}
|
55
app/src/hook/css.ts
Normal file
@ -0,0 +1,55 @@
|
||||
import { isLightColorTheme, parseColor } from "./color";
|
||||
|
||||
export function setDefaultCss() {
|
||||
// 改变默认颜色
|
||||
document.body.style.setProperty('--el-color-primary', 'var(--main-color)');
|
||||
document.body.style.setProperty('--el-color-primary-light-9', 'var(--main-color)');
|
||||
document.body.style.setProperty('--el-color-primary-light-3', 'var(--main-color)');
|
||||
document.body.style.setProperty('--el-text-color-secondary', 'var(--foreground)');
|
||||
document.body.style.setProperty('--el-text-color-regular', 'var(--foreground)');
|
||||
document.body.style.setProperty('--el-border-color', 'var(--main-color)');
|
||||
document.body.style.setProperty('--el-fill-color-blank', 'var(--sidebar)');
|
||||
document.body.style.setProperty('--el-fill-color-light', 'var(--vscode-button-hoverBackground)');
|
||||
document.body.style.setProperty('--el-switch-on-color', 'var(--main-color)');
|
||||
document.body.style.setProperty('--el-border', 'var(--sidebar)');
|
||||
document.body.style.setProperty('--el-border-color-light', 'var(--sidebar)');
|
||||
document.body.style.setProperty('--el-border-color-lighter', 'var(--sidebar)');
|
||||
document.body.style.setProperty('--el-bg-color-overlay', 'var(--sidebar)');
|
||||
document.body.style.setProperty('--el-color-info-light-9', 'var(--main-color)');
|
||||
document.body.style.setProperty('--el-color-info', 'var(--foreground)');
|
||||
document.body.style.setProperty('--el-color-info-light-8', 'var(--main-color)');
|
||||
document.body.style.setProperty('--el-fill-color-light', 'var(--sidebar-item-selected)');
|
||||
document.body.style.setProperty('--el-color-primary-dark-2', 'var(--main-light-color)');
|
||||
// document.body.style.setProperty('--el-color-white', 'var(--background)');
|
||||
|
||||
// 设置全局宏
|
||||
document.body.style.setProperty('--time-scale-height', '30px');
|
||||
document.body.style.setProperty('--vcd-render-padding', '30px');
|
||||
document.body.style.setProperty('--sidebar-width', '330px');
|
||||
document.body.style.setProperty('--toolbar-height', '60px');
|
||||
|
||||
// 下面是 get style
|
||||
const style = getComputedStyle(document.documentElement);
|
||||
// 根据颜色亮度来设置额外的宏
|
||||
const bgColorString = style.getPropertyValue('--background');
|
||||
|
||||
const color = parseColor(bgColorString);
|
||||
if (!color) {
|
||||
return;
|
||||
}
|
||||
|
||||
const { r, g, b } = color;
|
||||
if (isLightColorTheme(r, g, b)) {
|
||||
setExtraLightColorCss();
|
||||
} else {
|
||||
setExtraDarkColorCss();
|
||||
}
|
||||
}
|
||||
|
||||
function setExtraLightColorCss() {
|
||||
document.body.style.setProperty('--vline-stroke-color', '#ddd');
|
||||
}
|
||||
|
||||
function setExtraDarkColorCss() {
|
||||
document.body.style.setProperty('--vline-stroke-color', '#333');
|
||||
}
|
31
app/src/hook/global.ts
Normal file
@ -0,0 +1,31 @@
|
||||
import { reactive } from 'vue';
|
||||
import * as Color from './color';
|
||||
|
||||
type SupportLanguage = 'zh' | 'en' | 'zhTw' | 'ja' | 'de' | 'ko' | 'ru' | 'fr' | 'ar';
|
||||
|
||||
interface IGlobalSetting {
|
||||
language: SupportLanguage
|
||||
}
|
||||
|
||||
export const globalSetting = reactive<IGlobalSetting>({
|
||||
language: 'zh'
|
||||
});
|
||||
|
||||
|
||||
let themeColor: 'light' | 'dark' | undefined = undefined;
|
||||
|
||||
export function getThemeColor(): 'light' | 'dark' {
|
||||
if (themeColor) {
|
||||
return themeColor;
|
||||
}
|
||||
const rootStyles = getComputedStyle(document.documentElement);
|
||||
const backgroundColorString = rootStyles.getPropertyValue('--background');
|
||||
const backgroundColor = Color.parseColor(backgroundColorString);
|
||||
if (backgroundColor) {
|
||||
const isLight = Color.isLightColorTheme(backgroundColor.r, backgroundColor.g, backgroundColor.b);
|
||||
themeColor = isLight ? 'light' : 'dark';
|
||||
return themeColor;
|
||||
}
|
||||
|
||||
return 'dark';
|
||||
}
|
@ -106,5 +106,11 @@
|
||||
"connected": "متصل",
|
||||
"disconnected": "غير متصل",
|
||||
"debug": "تصحيح",
|
||||
"connect": "اتصال"
|
||||
"connect": "اتصال",
|
||||
"setting.general-color-setting": "إعدادات الألوان العامة",
|
||||
"choose-a-project-debug": "اختر مشروعًا لتصحيحه",
|
||||
"model": "النموذج",
|
||||
"server-provider": "مزود الخدمة",
|
||||
"api-root-url": "مسار جذر API",
|
||||
"api-token": "مفتاح API"
|
||||
}
|
@ -106,5 +106,11 @@
|
||||
"connected": "Verbunden",
|
||||
"disconnected": "Getrennt",
|
||||
"debug": "Debuggen",
|
||||
"connect": "Verbinden"
|
||||
"connect": "Verbinden",
|
||||
"setting.general-color-setting": "Allgemeine Farbeinstellungen",
|
||||
"choose-a-project-debug": "Wählen Sie ein Projekt zum Debuggen aus",
|
||||
"model": "Modell",
|
||||
"server-provider": "Dienstanbieter",
|
||||
"api-root-url": "API-Stammpfad",
|
||||
"api-token": "API-Schlüssel"
|
||||
}
|
@ -106,5 +106,11 @@
|
||||
"connected": "Connecté",
|
||||
"disconnected": "Déconnecté",
|
||||
"debug": "Déboguer",
|
||||
"connect": "Connexion"
|
||||
"connect": "Connexion",
|
||||
"setting.general-color-setting": "Paramètres de couleur généraux",
|
||||
"choose-a-project-debug": "Sélectionnez un projet à déboguer",
|
||||
"model": "Modèle",
|
||||
"server-provider": "Fournisseur de services",
|
||||
"api-root-url": "Chemin racine de l'API",
|
||||
"api-token": "Clé API"
|
||||
}
|
@ -106,5 +106,11 @@
|
||||
"connected": "接続済み",
|
||||
"disconnected": "切断されました",
|
||||
"debug": "デバッグ",
|
||||
"connect": "接続"
|
||||
"connect": "接続",
|
||||
"setting.general-color-setting": "一般的な色設定",
|
||||
"choose-a-project-debug": "デバッグするプロジェクトを選択",
|
||||
"model": "モデル",
|
||||
"server-provider": "サービスプロバイダー",
|
||||
"api-root-url": "APIルートパス",
|
||||
"api-token": "APIキー"
|
||||
}
|
@ -106,5 +106,11 @@
|
||||
"connected": "연결됨",
|
||||
"disconnected": "연결 해제됨",
|
||||
"debug": "디버그",
|
||||
"connect": "연결"
|
||||
"connect": "연결",
|
||||
"setting.general-color-setting": "일반 색상 설정",
|
||||
"choose-a-project-debug": "디버깅할 프로젝트 선택",
|
||||
"model": "모델",
|
||||
"server-provider": "서비스 제공자",
|
||||
"api-root-url": "API 루트 경로",
|
||||
"api-token": "API 키"
|
||||
}
|
@ -106,5 +106,11 @@
|
||||
"connected": "Подключено",
|
||||
"disconnected": "Отключено",
|
||||
"debug": "Отладка",
|
||||
"connect": "Подключение"
|
||||
"connect": "Подключение",
|
||||
"setting.general-color-setting": "Общие настройки цвета",
|
||||
"choose-a-project-debug": "Выберите проект для отладки",
|
||||
"model": "Модель",
|
||||
"server-provider": "Поставщик услуг",
|
||||
"api-root-url": "Корневой путь API",
|
||||
"api-token": "API-ключ"
|
||||
}
|
@ -106,5 +106,11 @@
|
||||
"connected": "已连接",
|
||||
"disconnected": "未连接",
|
||||
"debug": "调试",
|
||||
"connect": "连接"
|
||||
"connect": "连接",
|
||||
"setting.general-color-setting": "通用颜色设置",
|
||||
"choose-a-project-debug": "选择一个项目进行调试",
|
||||
"model": "模型",
|
||||
"server-provider": "服务提供者",
|
||||
"api-root-url": "API 根路径",
|
||||
"api-token": "API 密钥"
|
||||
}
|
@ -106,5 +106,11 @@
|
||||
"connected": "已連線",
|
||||
"disconnected": "已斷開連接",
|
||||
"debug": "偵錯",
|
||||
"connect": "連接"
|
||||
"connect": "連接",
|
||||
"setting.general-color-setting": "通用顏色設定",
|
||||
"choose-a-project-debug": "選擇一個項目進行調試",
|
||||
"model": "模型",
|
||||
"server-provider": "服務提供者",
|
||||
"api-root-url": "API 根路徑",
|
||||
"api-token": "API 密鑰"
|
||||
}
|
@ -2,16 +2,32 @@
|
||||
<div class="about-container">
|
||||
|
||||
<span>
|
||||
<img src="/protocol.svg" alt="">
|
||||
<img src="/images/openmcp.svg" alt="">
|
||||
</span>
|
||||
|
||||
OpenMCP Client 0.0.1 由 @锦恢 开发
|
||||
<p>
|
||||
OpenMCP Client 0.0.1 由 OpenMCP@<a href="https://www.zhihu.com/people/can-meng-zhong-de-che-xian">锦恢</a> 开发
|
||||
</p>
|
||||
|
||||
<p>软件已开源 <a href="https://github.com/LSTM-Kirigaya/openmcp-client" target="_blank">
|
||||
<p>
|
||||
软件已开源 <a href="https://github.com/LSTM-Kirigaya/openmcp-client" target="_blank">
|
||||
LSTM-Kirigaya/openmcp-client
|
||||
</a></p>
|
||||
</a>
|
||||
<br>
|
||||
请遵循开源协议进行分发和二次开发。
|
||||
</p>
|
||||
|
||||
<p>请遵循开源协议进行分发和二次开发。</p>
|
||||
<p>
|
||||
如果感兴趣,欢迎加入我们的QQ群和我们讨论
|
||||
</p>
|
||||
<el-button
|
||||
class="join-qq"
|
||||
type="primary"
|
||||
@click="joinQQGroup('https://qm.qq.com/cgi-bin/qm/qr?k=C6ZUTZvfqWoI12lWe7L93cWa1hUsuVT0&jump_from=webapi&authKey=McW6B1ogTPjPDrCyGttS890tMZGQ1KB3QLuG4aqVNRaYp4vlTSgf2c6dMcNjMuBD')"
|
||||
>
|
||||
<span class="iconfont icon-QQ"></span>
|
||||
加入 OpenMCP 技术群
|
||||
</el-button>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@ -19,6 +35,11 @@
|
||||
import { defineComponent } from 'vue';
|
||||
|
||||
defineComponent({ name: 'about' });
|
||||
|
||||
function joinQQGroup(url: string) {
|
||||
window.open(url, '_blank');
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
<style>
|
||||
@ -30,4 +51,23 @@ defineComponent({ name: 'about' });
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.about-container > span > img {
|
||||
height: 150px;
|
||||
width: 150px;
|
||||
}
|
||||
|
||||
.about-container > .qr-code {
|
||||
height: 180px;
|
||||
border: 2px solid transparent; /* 设置边框宽度,但颜色透明 */
|
||||
border-image: linear-gradient(to bottom right, #7DDCEB, #CB81DA);
|
||||
border-image-slice: 1; /* 确保渐变覆盖整个边框 */
|
||||
background: white; /* 可选:防止内容穿透 */
|
||||
}
|
||||
|
||||
.join-qq .iconfont {
|
||||
font-size: 20px;
|
||||
margin-right: 6px;
|
||||
}
|
||||
|
||||
</style>
|
@ -1,6 +1,6 @@
|
||||
<template>
|
||||
<div class="debug-welcome">
|
||||
<span>选择一个项目进行调试</span>
|
||||
<span>{{ t('choose-a-project-debug') }}</span>
|
||||
<div class="welcome-container">
|
||||
<span
|
||||
class="debug-option"
|
||||
@ -99,4 +99,8 @@ const debugOptions = [
|
||||
font-size: 48px;
|
||||
}
|
||||
|
||||
.debug-welcome {
|
||||
user-select: none;
|
||||
}
|
||||
|
||||
</style>
|
94
app/src/views/setting/api.vue
Normal file
@ -0,0 +1,94 @@
|
||||
<template>
|
||||
<div class="setting-section">
|
||||
<h2>{{ "API" }}</h2>
|
||||
<div class="setting-option">
|
||||
<span>
|
||||
<span class="iconfont icon-company"></span>
|
||||
<span class="option-title">{{ t('server-provider') }}</span>
|
||||
</span>
|
||||
<div style="width: 160px;">
|
||||
<el-select
|
||||
name="language-setting"
|
||||
class="language-setting"
|
||||
v-model="llmManager.currentModelIndex"
|
||||
@change="onmodelchange">
|
||||
|
||||
<el-option v-for="(option, index) in llms" :value="index" :label="option.name" :key="index">
|
||||
<div class="llm-option">
|
||||
<img :src="option.icon" alt="">
|
||||
<span>{{ option.name }}</span>
|
||||
</div>
|
||||
</el-option>
|
||||
</el-select>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 根据不同模型展示不同的接入点 -->
|
||||
<div v-if="false">
|
||||
|
||||
</div>
|
||||
<div v-else>
|
||||
<div class="setting-option">
|
||||
<span>
|
||||
<span class="iconfont icon-llm"></span>
|
||||
<span class="option-title">{{ t('model') }}</span>
|
||||
</span>
|
||||
<div style="width: 160px;">
|
||||
<el-select name="language-setting" class="language-setting"
|
||||
v-model="llms[llmManager.currentModelIndex].userModel"
|
||||
@change="onmodelchange"
|
||||
>
|
||||
<el-option v-for="option in llms[llmManager.currentModelIndex].models"
|
||||
:value="option"
|
||||
:label="option"
|
||||
:key="option"
|
||||
></el-option>
|
||||
</el-select>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="setting-option">
|
||||
<span>
|
||||
<span class="iconfont icon-url-line"></span>
|
||||
<span class="option-title">{{ t('api-root-url') }}</span>
|
||||
</span>
|
||||
<div style="width: 240px;">
|
||||
<el-input
|
||||
v-model="llms[llmManager.currentModelIndex].baseUrl"
|
||||
placeholder="https://"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="setting-option">
|
||||
<span>
|
||||
<span class="iconfont icon-token"></span>
|
||||
<span class="option-title">{{ t('api-token') }}</span>
|
||||
</span>
|
||||
<div style="width: 240px;">
|
||||
<el-input
|
||||
v-model="llms[llmManager.currentModelIndex].userToken"
|
||||
show-password
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { defineComponent } from 'vue';
|
||||
import { llmManager, llms, onmodelchange } from './llm';
|
||||
import { useI18n } from 'vue-i18n';
|
||||
|
||||
defineComponent({ name: 'api' });
|
||||
const { t } = useI18n();
|
||||
|
||||
|
||||
|
||||
</script>
|
||||
|
||||
<style>
|
||||
|
||||
</style>
|
42
app/src/views/setting/appearance.vue
Normal file
@ -0,0 +1,42 @@
|
||||
<template>
|
||||
<div class="setting-section">
|
||||
<h2>{{ t('general-setting') }}</h2>
|
||||
<div class="setting-option">
|
||||
<span>
|
||||
<span class="iconfont icon-i18n"></span>
|
||||
<span class="option-title">{{ t('language-setting') }}</span>
|
||||
</span>
|
||||
<div style="width: 100px;">
|
||||
<el-select name="language-setting" class="language-setting" v-model="locale" @change="onlanguagechange">
|
||||
<el-option v-for="option in languageSetting.options" :value="option.value" :label="option.text"
|
||||
:key="option.value">
|
||||
</el-option>
|
||||
</el-select>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { defineComponent, ref } from 'vue';
|
||||
import { languageSetting } from './language';
|
||||
import { useI18n } from 'vue-i18n';
|
||||
import { globalSetting } from '@/hook/global';
|
||||
|
||||
defineComponent({ name: 'appearance' });
|
||||
|
||||
const { t, locale } = useI18n();
|
||||
locale.value = globalSetting.language;
|
||||
|
||||
const currentLanguage = ref('简体中文');
|
||||
|
||||
function onlanguagechange(code: string) {
|
||||
const option = languageSetting.options.find(item => item.value === code);
|
||||
if (option) {
|
||||
currentLanguage.value = option.text;
|
||||
}
|
||||
// languageDialogShow.value = true;
|
||||
}
|
||||
</script>
|
||||
|
||||
<style></style>
|
45
app/src/views/setting/color.ts
Normal file
@ -0,0 +1,45 @@
|
||||
import { reactive } from 'vue';
|
||||
|
||||
import i18n from '@/i18n';
|
||||
import { parseColor } from '@/hook/color';
|
||||
import { globalSetting } from '@/hook/global';
|
||||
|
||||
const { t, locale } = i18n.global;
|
||||
locale.value = globalSetting.language;
|
||||
|
||||
export const colorManager = reactive({
|
||||
mainColor: 'white',
|
||||
|
||||
initColor() {
|
||||
const rootStyles = getComputedStyle(document.documentElement);
|
||||
this.mainColor = rootStyles.getPropertyValue('--main-color');
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* @description 通用颜色设置发生变时
|
||||
* @param {string} colorString 用户选择的颜色的字符串
|
||||
*/
|
||||
export function onGeneralColorChange(colorString: string) {
|
||||
const color = parseColor(colorString);
|
||||
if (!color) {
|
||||
return;
|
||||
}
|
||||
const { r, g, b } = color;
|
||||
|
||||
document.documentElement.style.setProperty(
|
||||
'--main-color', `rgb(${r}, ${g}, ${b})`);
|
||||
|
||||
document.documentElement.style.setProperty(
|
||||
'--main-light-color', `rgba(${r}, ${g}, ${b}, 0.7)`);
|
||||
}
|
||||
|
||||
export const predefinedColors = [
|
||||
'#ff4500',
|
||||
'#ff8c00',
|
||||
'#ffd700',
|
||||
'#90ee90',
|
||||
'#00ced1',
|
||||
'#1e90ff',
|
||||
'#c71585'
|
||||
];
|
29
app/src/views/setting/general.vue
Normal file
@ -0,0 +1,29 @@
|
||||
<template>
|
||||
<div class="setting-section">
|
||||
<h2>{{ t('appearance-setting') }}</h2>
|
||||
<div class="setting-option">
|
||||
<span class="option-title">
|
||||
<span class="iconfont icon-bg-colors"></span>
|
||||
|
||||
{{ t('setting.general-color-setting') }}
|
||||
</span>
|
||||
<div class="option-group">
|
||||
<div style="height: 20px; width: 20px;"></div>
|
||||
<el-color-picker v-model="colorManager.mainColor" @change="onGeneralColorChange"
|
||||
:predefine="predefinedColors" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { defineComponent } from 'vue';
|
||||
import { colorManager, onGeneralColorChange, predefinedColors } from './color';
|
||||
import { useI18n } from 'vue-i18n';
|
||||
|
||||
defineComponent({ name: 'general' });
|
||||
const { t } = useI18n();
|
||||
|
||||
</script>
|
||||
|
||||
<style></style>
|
@ -1,12 +1,116 @@
|
||||
<template>
|
||||
<div></div>
|
||||
<div class="setting-container">
|
||||
<General></General>
|
||||
<Api></Api>
|
||||
<Appearance></Appearance>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { defineComponent } from 'vue';
|
||||
import { defineComponent, ref, onMounted } from 'vue';
|
||||
|
||||
import { colorManager } from './color';
|
||||
|
||||
import General from './general.vue';
|
||||
import Api from './api.vue';
|
||||
import Appearance from './appearance.vue';
|
||||
|
||||
defineComponent({ name: 'setting' });
|
||||
|
||||
onMounted(() => {
|
||||
colorManager.initColor();
|
||||
});
|
||||
|
||||
</script>
|
||||
|
||||
<style>
|
||||
.setting-container {
|
||||
position: relative;
|
||||
width: 60%;
|
||||
padding: 5px 20px;
|
||||
height: fit-content;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
border-radius: .5em;
|
||||
}
|
||||
|
||||
.setting-drag {
|
||||
height: 20px;
|
||||
width: 100%;
|
||||
background-color: var(--main-color);
|
||||
position: relative;
|
||||
border-radius: .5em .5em 0 0;
|
||||
}
|
||||
|
||||
.setting-container .el-scrollbar {
|
||||
width: 400px;
|
||||
user-select: none;
|
||||
}
|
||||
|
||||
.setting-section {
|
||||
padding: 10px;
|
||||
margin: 10px;
|
||||
border-radius: .3em;
|
||||
min-height: 50px;
|
||||
}
|
||||
|
||||
.setting-option {
|
||||
margin: 3px;
|
||||
margin-bottom: 10px;
|
||||
padding: 8px 12px;
|
||||
height: 40px;
|
||||
border-radius: .5em;
|
||||
background-color: var(--background);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
font-size: 0.9rem;
|
||||
}
|
||||
|
||||
.setting-option .iconfont {
|
||||
margin-right: 8px;
|
||||
font-size: 15px;
|
||||
}
|
||||
|
||||
.option-group {
|
||||
display: flex;
|
||||
width: fit-content;
|
||||
}
|
||||
|
||||
.option-title {
|
||||
font-size: 0.8rem;
|
||||
min-width: 80px;
|
||||
margin-right: 12px;
|
||||
user-select: none;
|
||||
}
|
||||
|
||||
.el-checkbox-button.is-checked:first-child .el-checkbox-button__inner,
|
||||
.el-checkbox-button__inner {
|
||||
font-size: 0.8rem !important;
|
||||
}
|
||||
|
||||
.el-slider__button {
|
||||
background-color: var(--background) !important;
|
||||
}
|
||||
|
||||
.el-switch__core .el-switch__action {
|
||||
background-color: var(--background) !important;
|
||||
}
|
||||
|
||||
.el-slider__stop {
|
||||
background-color: var(--vscode-foreground) !important;
|
||||
}
|
||||
|
||||
.llm-option img {
|
||||
height: 20px;
|
||||
width: 20px;
|
||||
margin-right: 7px;
|
||||
}
|
||||
|
||||
.llm-option {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
margin: 2px;
|
||||
}
|
||||
</style>
|
42
app/src/views/setting/language.ts
Normal file
@ -0,0 +1,42 @@
|
||||
import { reactive } from 'vue';
|
||||
|
||||
export const languageSetting = reactive({
|
||||
options: [
|
||||
{
|
||||
value: 'en',
|
||||
text: 'English'
|
||||
},
|
||||
{
|
||||
value: 'zh',
|
||||
text: '简体中文'
|
||||
},
|
||||
{
|
||||
value: 'zhTw',
|
||||
text: '繁體中文'
|
||||
},
|
||||
{
|
||||
value: 'ja',
|
||||
text: '日本語'
|
||||
},
|
||||
{
|
||||
value: 'ko',
|
||||
text: '한국어'
|
||||
},
|
||||
{
|
||||
value: 'de',
|
||||
text: 'Deutsch'
|
||||
},
|
||||
{
|
||||
value: 'fr',
|
||||
text: 'Français'
|
||||
},
|
||||
{
|
||||
value: 'ru',
|
||||
text: 'Русский'
|
||||
},
|
||||
{
|
||||
value: 'ar',
|
||||
text: 'العربية'
|
||||
}
|
||||
]
|
||||
});
|
114
app/src/views/setting/llm.ts
Normal file
@ -0,0 +1,114 @@
|
||||
import { reactive } from 'vue';
|
||||
|
||||
export const llms = reactive([
|
||||
{
|
||||
id: 'deepseek',
|
||||
name: 'DeepSeek',
|
||||
baseUrl: 'https://api.deepseek.com/v1',
|
||||
models: ['deepseek-chat', 'deepseek-coder', 'deepseek-math'],
|
||||
icon: '/images/deepseek.com.ico',
|
||||
provider: 'DeepSeek',
|
||||
isOpenAICompatible: true,
|
||||
description: '深度求索推出的大模型,擅长中文和代码',
|
||||
website: 'https://www.deepseek.com',
|
||||
userToken: '',
|
||||
userModel: 'deepseek-chat'
|
||||
},
|
||||
{
|
||||
id: 'openai',
|
||||
name: 'OpenAI',
|
||||
baseUrl: 'https://api.openai.com/v1',
|
||||
models: ['gpt-4-turbo', 'gpt-4', 'gpt-3.5-turbo'],
|
||||
icon: '/images/openai.com.ico',
|
||||
provider: 'OpenAI',
|
||||
isOpenAICompatible: true,
|
||||
description: 'OpenAI官方API',
|
||||
website: 'https://openai.com',
|
||||
userToken: '',
|
||||
userModel: 'gpt-4-turbo'
|
||||
},
|
||||
{
|
||||
id: 'mistral',
|
||||
name: 'Mistral',
|
||||
baseUrl: 'https://api.mistral.ai/v1',
|
||||
models: ['mistral-tiny', 'mistral-small', 'mistral-medium'],
|
||||
icon: '/images/mistral.ai.ico',
|
||||
provider: 'Mistral AI',
|
||||
isOpenAICompatible: true,
|
||||
description: '欧洲开源大模型代表',
|
||||
website: 'https://mistral.ai',
|
||||
userToken: '',
|
||||
userModel: 'mistral-tiny'
|
||||
},
|
||||
{
|
||||
id: 'ollama',
|
||||
name: 'Ollama (Local)',
|
||||
baseUrl: 'http://localhost:11434/v1',
|
||||
models: ['llama2', 'mistral', 'codellama'],
|
||||
icon: '/images/ollama.png',
|
||||
provider: 'Ollama',
|
||||
isOpenAICompatible: true,
|
||||
description: '本地运行的大模型',
|
||||
website: 'https://ollama.com',
|
||||
userToken: '',
|
||||
userModel: 'llama2'
|
||||
},
|
||||
{
|
||||
id: 'groq',
|
||||
name: 'Groq',
|
||||
baseUrl: 'https://api.groq.com/openai/v1',
|
||||
models: ['mixtral-8x7b-32768', 'llama2-70b-4096'],
|
||||
icon: '/images/grok.com.png',
|
||||
provider: 'Groq',
|
||||
isOpenAICompatible: true,
|
||||
description: '超高速推理API',
|
||||
website: 'https://groq.com',
|
||||
userToken: '',
|
||||
userModel: 'mixtral-8x7b-32768'
|
||||
},
|
||||
{
|
||||
id: 'perplexity',
|
||||
name: 'Perplexity',
|
||||
baseUrl: 'https://api.perplexity.ai/v1',
|
||||
models: ['pplx-7b-online', 'pplx-70b-online'],
|
||||
icon: '/images/perplexity.ai.ico',
|
||||
provider: 'Perplexity AI',
|
||||
isOpenAICompatible: true,
|
||||
description: '联网搜索增强的大模型',
|
||||
website: 'https://www.perplexity.ai',
|
||||
userToken: '',
|
||||
userModel: 'pplx-7b-online'
|
||||
},
|
||||
{
|
||||
id: 'kimi',
|
||||
name: 'Kimi Chat',
|
||||
baseUrl: 'https://api.moonshot.cn/v1',
|
||||
models: ['moonshot-v1-8k', 'moonshot-v1-32k', 'moonshot-v1-128k'],
|
||||
icon: '/images/kimichat.cn.png',
|
||||
provider: '月之暗面 (Moonshot AI)',
|
||||
isOpenAICompatible: true,
|
||||
description: '支持超长上下文的中文大模型,上下文窗口高达128K',
|
||||
website: 'https://kimi.moonshot.cn',
|
||||
userToken: '',
|
||||
userModel: 'moonshot-v1-8k'
|
||||
}
|
||||
]);
|
||||
|
||||
export const llmManager = reactive({
|
||||
currentModelIndex: 0,
|
||||
});
|
||||
|
||||
export function onmodelchange() {
|
||||
console.log();
|
||||
|
||||
}
|
||||
|
||||
export async function save() {
|
||||
console.log();
|
||||
|
||||
}
|
||||
|
||||
export async function load() {
|
||||
console.log();
|
||||
|
||||
}
|
10
app/src/views/setting/util.ts
Normal file
@ -0,0 +1,10 @@
|
||||
const pinkLogStyle = 'background-color: #CB81DA; color: white; padding: 3px; border-radius: 3px;';
|
||||
const redLogStyle = 'background-color:rgb(227, 91, 49); color: white; padding: 3px; border-radius: 3px;';
|
||||
|
||||
export function pinkLog(message: string) {
|
||||
console.log('%c' + message, pinkLogStyle);
|
||||
}
|
||||
|
||||
export function redLog(message: string) {
|
||||
console.log('%c' + message, redLogStyle);
|
||||
}
|
@ -1,41 +1,41 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"target": "esnext",
|
||||
"module": "esnext",
|
||||
"strict": true,
|
||||
"jsx": "preserve",
|
||||
"moduleResolution": "node",
|
||||
"skipLibCheck": true,
|
||||
"esModuleInterop": true,
|
||||
"allowSyntheticDefaultImports": true,
|
||||
"forceConsistentCasingInFileNames": true,
|
||||
"resolveJsonModule": true,
|
||||
"useDefineForClassFields": true,
|
||||
"sourceMap": true,
|
||||
"baseUrl": ".",
|
||||
"types": [
|
||||
"webpack-env"
|
||||
],
|
||||
"paths": {
|
||||
"@/*": [
|
||||
"src/*"
|
||||
]
|
||||
},
|
||||
"lib": [
|
||||
"esnext",
|
||||
"dom",
|
||||
"dom.iterable",
|
||||
"scripthost"
|
||||
]
|
||||
},
|
||||
"include": [
|
||||
"src/**/*.ts",
|
||||
"src/**/*.tsx",
|
||||
"src/**/*.vue",
|
||||
"tests/**/*.ts",
|
||||
"tests/**/*.tsx"
|
||||
],
|
||||
"exclude": [
|
||||
"node_modules"
|
||||
]
|
||||
"compilerOptions": {
|
||||
"target": "esnext",
|
||||
"module": "esnext",
|
||||
"strict": true,
|
||||
"jsx": "preserve",
|
||||
"moduleResolution": "node",
|
||||
"skipLibCheck": true,
|
||||
"esModuleInterop": true,
|
||||
"allowSyntheticDefaultImports": true,
|
||||
"forceConsistentCasingInFileNames": true,
|
||||
"resolveJsonModule": true,
|
||||
"useDefineForClassFields": true,
|
||||
"sourceMap": true,
|
||||
"baseUrl": ".",
|
||||
"types": [
|
||||
"webpack-env"
|
||||
],
|
||||
"paths": {
|
||||
"@/*": [
|
||||
"src/*"
|
||||
]
|
||||
},
|
||||
"lib": [
|
||||
"esnext",
|
||||
"dom",
|
||||
"dom.iterable",
|
||||
"scripthost"
|
||||
]
|
||||
},
|
||||
"include": [
|
||||
"src/**/*.ts",
|
||||
"src/**/*.tsx",
|
||||
"src/**/*.vue",
|
||||
"tests/**/*.ts",
|
||||
"tests/**/*.tsx"
|
||||
],
|
||||
"exclude": [
|
||||
"node_modules"
|
||||
]
|
||||
}
|
22
app/webpack.config.js
Normal file
@ -0,0 +1,22 @@
|
||||
const AutoImport = require('unplugin-auto-import/webpack')
|
||||
const Components = require('unplugin-vue-components/webpack')
|
||||
const { ElementPlusResolver } = require('unplugin-vue-components/resolvers')
|
||||
|
||||
module.exports = {
|
||||
plugins: [
|
||||
AutoImport({
|
||||
resolvers: [ElementPlusResolver()],
|
||||
}),
|
||||
Components({
|
||||
resolvers: [ElementPlusResolver()],
|
||||
}),
|
||||
new webpack.DefinePlugin({
|
||||
__VUE_PROD_HYDRATION_MISMATCH_DETAILS__: false,
|
||||
})
|
||||
],
|
||||
resolve: {
|
||||
fallback: {
|
||||
"stream": false
|
||||
}
|
||||
},
|
||||
};
|