添加数据库工具执行

This commit is contained in:
junleea 2025-08-20 22:22:50 +08:00
parent ad5671fc28
commit 37b2ad396f
11 changed files with 998 additions and 4 deletions

9
components.d.ts vendored
View File

@ -8,11 +8,13 @@ export {}
declare module '@vue/runtime-core' {
export interface GlobalComponents {
Countup: typeof import('./src/components/countup.vue')['default']
ElAside: typeof import('element-plus/es')['ElAside']
ElAvatar: typeof import('element-plus/es')['ElAvatar']
ElButton: typeof import('element-plus/es')['ElButton']
ElCard: typeof import('element-plus/es')['ElCard']
ElCheckbox: typeof import('element-plus/es')['ElCheckbox']
ElCol: typeof import('element-plus/es')['ElCol']
ElContainer: typeof import('element-plus/es')['ElContainer']
ElDatePicker: typeof import('element-plus/es')['ElDatePicker']
ElDescriptions: typeof import('element-plus/es')['ElDescriptions']
ElDescriptionsItem: typeof import('element-plus/es')['ElDescriptionsItem']
@ -26,12 +28,15 @@ declare module '@vue/runtime-core' {
ElIcon: typeof import('element-plus/es')['ElIcon']
ElInput: typeof import('element-plus/es')['ElInput']
ElInputNumber: typeof import('element-plus/es')['ElInputNumber']
ElLink: typeof import('element-plus/es')['ElLink']
ElMain: typeof import('element-plus/es')['ElMain']
ElMenu: typeof import('element-plus/es')['ElMenu']
ElMenuItem: typeof import('element-plus/es')['ElMenuItem']
ElOption: typeof import('element-plus/es')['ElOption']
ElPagination: typeof import('element-plus/es')['ElPagination']
ElProgress: typeof import('element-plus/es')['ElProgress']
ElRow: typeof import('element-plus/es')['ElRow']
ElScrollbar: typeof import('element-plus/es')['ElScrollbar']
ElSelect: typeof import('element-plus/es')['ElSelect']
ElSubMenu: typeof import('element-plus/es')['ElSubMenu']
ElSwitch: typeof import('element-plus/es')['ElSwitch']
@ -42,6 +47,7 @@ declare module '@vue/runtime-core' {
ElTimeline: typeof import('element-plus/es')['ElTimeline']
ElTimelineItem: typeof import('element-plus/es')['ElTimelineItem']
ElTooltip: typeof import('element-plus/es')['ElTooltip']
ElTree: typeof import('element-plus/es')['ElTree']
ElUpload: typeof import('element-plus/es')['ElUpload']
Header: typeof import('./src/components/header.vue')['default']
RouterLink: typeof import('vue-router')['RouterLink']
@ -55,4 +61,7 @@ declare module '@vue/runtime-core' {
Upload_file2: typeof import('./src/components/upload_file2.vue')['default']
UploadFile: typeof import('./src/components/upload-file.vue')['default']
}
export interface ComponentCustomProperties {
vLoading: typeof import('element-plus/es')['ElLoadingDirective']
}
}

181
package-lock.json generated
View File

@ -21,6 +21,7 @@
"dompurify": "^3.2.4",
"echarts": "^5.5.0",
"echarts-wordcloud": "^2.1.0",
"el-table-horizontal-scroll": "^1.2.5",
"element-plus": "^2.6.3",
"highlight.js": "^11.11.1",
"js-md5": "^0.8.3",
@ -1578,6 +1579,32 @@
"proxy-from-env": "^1.1.0"
}
},
"node_modules/babel-helper-vue-jsx-merge-props": {
"version": "2.0.3",
"resolved": "https://registry.npmjs.org/babel-helper-vue-jsx-merge-props/-/babel-helper-vue-jsx-merge-props-2.0.3.tgz",
"integrity": "sha512-gsLiKK7Qrb7zYJNgiXKpXblxbV5ffSwR0f5whkPAaBAR4fhi6bwRZxX9wBlIc5M/v8CCkXUbXZL4N/nSE97cqg=="
},
"node_modules/babel-runtime": {
"version": "6.26.0",
"resolved": "https://registry.npmjs.org/babel-runtime/-/babel-runtime-6.26.0.tgz",
"integrity": "sha512-ITKNuq2wKlW1fJg9sSW52eepoYgZBggvOAHC0u/CYu/qxQ9EVzThCgR69BnSXLHjy2f7SY5zaQ4yt7H9ZVxY2g==",
"dependencies": {
"core-js": "^2.4.0",
"regenerator-runtime": "^0.11.0"
}
},
"node_modules/babel-runtime/node_modules/core-js": {
"version": "2.6.12",
"resolved": "https://registry.npmjs.org/core-js/-/core-js-2.6.12.tgz",
"integrity": "sha512-Kb2wC0fvsWfQrgk8HU5lW6U/Lcs8+9aaYcy4ZFc6DDlo4nZ7n70dEgE5rtR0oG6ufKDUnrwfWL1mXR5ljDatrQ==",
"deprecated": "core-js@<3.23.3 is no longer maintained and not recommended for usage due to the number of issues. Because of the V8 engine whims, feature detection in old core-js versions could cause a slowdown up to 100x even if nothing is polyfilled. Some versions have web compatibility issues. Please, upgrade your dependencies to the actual version of core-js.",
"hasInstallScript": true
},
"node_modules/babel-runtime/node_modules/regenerator-runtime": {
"version": "0.11.1",
"resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.11.1.tgz",
"integrity": "sha512-MguG95oij0fC3QV3URf4V2SDYGJhJnJGqvIIgdECeODCT98wSWDAJ94SSuVpYQUoTcGUIL6L4yNB7j1DFFHSBg=="
},
"node_modules/balanced-match": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
@ -1775,6 +1802,16 @@
"proto-list": "~1.2.1"
}
},
"node_modules/core-js": {
"version": "3.45.0",
"resolved": "https://registry.npmjs.org/core-js/-/core-js-3.45.0.tgz",
"integrity": "sha512-c2KZL9lP4DjkN3hk/an4pWn5b5ZefhRJnAc42n6LJ19kSnbeRbdQZE5dSeE2LBol1OwJD3X1BQvFTAsa8ReeDA==",
"hasInstallScript": true,
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/core-js"
}
},
"node_modules/cose-base": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/cose-base/-/cose-base-1.0.3.tgz",
@ -2371,6 +2408,14 @@
"url": "https://github.com/sponsors/wooorm"
}
},
"node_modules/deepmerge": {
"version": "1.5.2",
"resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-1.5.2.tgz",
"integrity": "sha512-95k0GDqvBjZavkuvzx/YqVLv/6YYa17fz6ILMSf7neqQITCPbnfEnQvEgMPNjH4kgobe7+WIL0yJEHku+H3qtQ==",
"engines": {
"node": ">=0.10.0"
}
},
"node_modules/delaunator": {
"version": "5.0.1",
"resolved": "https://registry.npmjs.org/delaunator/-/delaunator-5.0.1.tgz",
@ -2490,6 +2535,80 @@
"url": "https://github.com/sponsors/isaacs"
}
},
"node_modules/el-table-horizontal-scroll": {
"version": "1.2.5",
"resolved": "https://registry.npmjs.org/el-table-horizontal-scroll/-/el-table-horizontal-scroll-1.2.5.tgz",
"integrity": "sha512-2Ays+8skp64Yl5YE2Kpa/9lJ720jPn1ooNSc2LKiF0ECiXPEoBZ5hhd144Inp1JATs5of4YzNwNd9L/Xy397GQ==",
"dependencies": {
"core-js": "^3.6.5",
"element-ui": "^2.15.6",
"lodash": "^4.17.21",
"throttle-debounce": "^5.0.0",
"vue": "^2.6.11",
"vue-route": "^1.5.1",
"vue-router": "^3.5.3"
}
},
"node_modules/el-table-horizontal-scroll/node_modules/@vue/compiler-sfc": {
"version": "2.7.16",
"resolved": "https://registry.npmjs.org/@vue/compiler-sfc/-/compiler-sfc-2.7.16.tgz",
"integrity": "sha512-KWhJ9k5nXuNtygPU7+t1rX6baZeqOYLEforUPjgNDBnLicfHCoi48H87Q8XyLZOrNNsmhuwKqtpDQWjEFe6Ekg==",
"dependencies": {
"@babel/parser": "^7.23.5",
"postcss": "^8.4.14",
"source-map": "^0.6.1"
},
"optionalDependencies": {
"prettier": "^1.18.2 || ^2.0.0"
}
},
"node_modules/el-table-horizontal-scroll/node_modules/async-validator": {
"version": "1.8.5",
"resolved": "https://registry.npmjs.org/async-validator/-/async-validator-1.8.5.tgz",
"integrity": "sha512-tXBM+1m056MAX0E8TL2iCjg8WvSyXu0Zc8LNtYqrVeyoL3+esHRZ4SieE9fKQyyU09uONjnMEjrNBMqT0mbvmA==",
"dependencies": {
"babel-runtime": "6.x"
}
},
"node_modules/el-table-horizontal-scroll/node_modules/element-ui": {
"version": "2.15.14",
"resolved": "https://registry.npmjs.org/element-ui/-/element-ui-2.15.14.tgz",
"integrity": "sha512-2v9fHL0ZGINotOlRIAJD5YuVB8V7WKxrE9Qy7dXhRipa035+kF7WuU/z+tEmLVPBcJ0zt8mOu1DKpWcVzBK8IA==",
"dependencies": {
"async-validator": "~1.8.1",
"babel-helper-vue-jsx-merge-props": "^2.0.0",
"deepmerge": "^1.2.0",
"normalize-wheel": "^1.0.1",
"resize-observer-polyfill": "^1.5.0",
"throttle-debounce": "^1.0.1"
},
"peerDependencies": {
"vue": "^2.5.17"
}
},
"node_modules/el-table-horizontal-scroll/node_modules/element-ui/node_modules/throttle-debounce": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/throttle-debounce/-/throttle-debounce-1.1.0.tgz",
"integrity": "sha512-XH8UiPCQcWNuk2LYePibW/4qL97+ZQ1AN3FNXwZRBNPPowo/NRU5fAlDCSNBJIYCKbioZfuYtMhG4quqoJhVzg==",
"engines": {
"node": ">=4"
}
},
"node_modules/el-table-horizontal-scroll/node_modules/vue": {
"version": "2.7.16",
"resolved": "https://registry.npmjs.org/vue/-/vue-2.7.16.tgz",
"integrity": "sha512-4gCtFXaAA3zYZdTp5s4Hl2sozuySsgz4jy1EnpBHNfpMa9dK1ZCG7viqBPCwXtmgc8nHqUsAu3G4gtmXkkY3Sw==",
"deprecated": "Vue 2 has reached EOL and is no longer actively maintained. See https://v2.vuejs.org/eol/ for more details.",
"dependencies": {
"@vue/compiler-sfc": "2.7.16",
"csstype": "^3.1.0"
}
},
"node_modules/el-table-horizontal-scroll/node_modules/vue-router": {
"version": "3.6.5",
"resolved": "https://registry.npmjs.org/vue-router/-/vue-router-3.6.5.tgz",
"integrity": "sha512-VYXZQLtjuvKxxcshuRAwjHnciqZVoXAjTjcqBTz4rKc8qih9g9pI3hbDjmqXaHdgL3v8pV6P8Z335XvHzESxLQ=="
},
"node_modules/element-plus": {
"version": "2.7.0",
"resolved": "https://registry.npmjs.org/element-plus/-/element-plus-2.7.0.tgz",
@ -3346,6 +3465,11 @@
"resolved": "https://registry.npmjs.org/is-url/-/is-url-1.2.4.tgz",
"integrity": "sha512-ITvGim8FhRiYe4IQ5uHSkj7pVaPDrCTkNd3yq3cV7iZAcJdHTUMPMEHcqSOy9xZ9qFenQCvi+2wjH9a1nXqHww=="
},
"node_modules/isarray": {
"version": "0.0.1",
"resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz",
"integrity": "sha512-D2S+3GLxWH+uhrNEcoh/fnmYeP8E8/zHl644d/jdA0g2uyXvy3sb0qxotE+ne0LtccHknQzWwZEzhak7oJ0COQ=="
},
"node_modules/isexe": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
@ -4445,6 +4569,11 @@
"node": ">=0.10.0"
}
},
"node_modules/normalize-wheel": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/normalize-wheel/-/normalize-wheel-1.0.1.tgz",
"integrity": "sha512-1OnlAPZ3zgrk8B91HyRj+eVv+kS5u+Z0SCsak6Xil/kmgEia50ga7zfkumayonZrImffAxPU/5WcyGhzetHNPA=="
},
"node_modules/normalize-wheel-es": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/normalize-wheel-es/-/normalize-wheel-es-1.2.0.tgz",
@ -4468,6 +4597,14 @@
"quansync": "^0.2.7"
}
},
"node_modules/page": {
"version": "1.11.6",
"resolved": "https://registry.npmjs.org/page/-/page-1.11.6.tgz",
"integrity": "sha512-P6e2JfzkBrPeFCIPplLP7vDDiU84RUUZMrWdsH4ZBGJ8OosnwFkcUkBHp1DTIjuipLliw9yQn/ZJsXZvarsO+g==",
"dependencies": {
"path-to-regexp": "~1.2.1"
}
},
"node_modules/path-data-parser": {
"version": "0.1.0",
"resolved": "https://registry.npmjs.org/path-data-parser/-/path-data-parser-0.1.0.tgz",
@ -4502,6 +4639,14 @@
"url": "https://github.com/sponsors/isaacs"
}
},
"node_modules/path-to-regexp": {
"version": "1.2.1",
"resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-1.2.1.tgz",
"integrity": "sha512-DBw9IhWfevR2zCVwEZURTuQNseCvu/Q9f5ZgqMCK0Rh61bDa4uyjPAOy9b55yKiPT59zZn+7uYKxmWwsguInwg==",
"dependencies": {
"isarray": "0.0.1"
}
},
"node_modules/pathe": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/pathe/-/pathe-1.1.2.tgz",
@ -4636,6 +4781,21 @@
"url": "https://opencollective.com/preact"
}
},
"node_modules/prettier": {
"version": "2.8.8",
"resolved": "https://registry.npmjs.org/prettier/-/prettier-2.8.8.tgz",
"integrity": "sha512-tdN8qQGvNjw4CHbY+XXk0JgCXn9QiF21a55rBe5LJAU+kDyC4WQn4+awm2Xfk2lQMk5fKup9XgzTZtGkjBdP9Q==",
"optional": true,
"bin": {
"prettier": "bin-prettier.js"
},
"engines": {
"node": ">=10.13.0"
},
"funding": {
"url": "https://github.com/prettier/prettier?sponsor=1"
}
},
"node_modules/prismjs": {
"version": "1.29.0",
"resolved": "https://registry.npmjs.org/prismjs/-/prismjs-1.29.0.tgz",
@ -4719,6 +4879,11 @@
"resolved": "https://registry.npmjs.org/resize-detector/-/resize-detector-0.3.0.tgz",
"integrity": "sha512-R/tCuvuOHQ8o2boRP6vgx8hXCCy87H1eY9V5imBYeVNyNVpuL9ciReSccLj2gDcax9+2weXy3bc8Vv+NRXeEvQ=="
},
"node_modules/resize-observer-polyfill": {
"version": "1.5.1",
"resolved": "https://registry.npmjs.org/resize-observer-polyfill/-/resize-observer-polyfill-1.5.1.tgz",
"integrity": "sha512-LwZrotdHOo12nQuZlHEmtuXdqGoOD0OhaxopaNFxWzInpEgaLWoVuAMbTzixuosCx2nEG58ngzW3vxdWoxIgdg=="
},
"node_modules/resolve": {
"version": "1.22.8",
"resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.8.tgz",
@ -5107,6 +5272,14 @@
"resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz",
"integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ=="
},
"node_modules/throttle-debounce": {
"version": "5.0.2",
"resolved": "https://registry.npmjs.org/throttle-debounce/-/throttle-debounce-5.0.2.tgz",
"integrity": "sha512-B71/4oyj61iNH0KeCamLuE2rmKuTO5byTOSVwECM5FA7TiAiAW+UqTKZ9ERueC4qvgSttUhdmq1mXC3kJqGX7A==",
"engines": {
"node": ">=12.22"
}
},
"node_modules/tiny-emitter": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/tiny-emitter/-/tiny-emitter-2.1.0.tgz",
@ -5583,6 +5756,14 @@
}
}
},
"node_modules/vue-route": {
"version": "1.5.1",
"resolved": "https://registry.npmjs.org/vue-route/-/vue-route-1.5.1.tgz",
"integrity": "sha512-RoeEWvSTk/Zasjx11En4XPyE1jXwuFQ4Itr4fzh1TOSMYefUddhhlHXmAGFFPn37J1YrEymm6sU/3IRTyu23Aw==",
"dependencies": {
"page": "^1.5.0"
}
},
"node_modules/vue-router": {
"version": "4.3.0",
"resolved": "https://registry.npmjs.org/vue-router/-/vue-router-4.3.0.tgz",

View File

@ -21,6 +21,7 @@
"dompurify": "^3.2.4",
"echarts": "^5.5.0",
"echarts-wordcloud": "^2.1.0",
"el-table-horizontal-scroll": "^1.2.5",
"element-plus": "^2.6.3",
"highlight.js": "^11.11.1",
"js-md5": "^0.8.3",

96
src/api/dbm.ts Normal file
View File

@ -0,0 +1,96 @@
import request from '@/utils/requst_tx_vp';
// dbm := router.Group("/dbm")
// dbm.POST("/run_sql", RunSQLHandler) // 运行SQL语句
// dbm.POST("/create_db_manage", CreateDBManageHandler) // 创建数据库管理
// dbm.POST("/get_db_manage", GetDBManageHandler) // 获取数据库管理信息
// dbm.POST("/get_sql_history", GetSQLRunHistoryHandler) // 获取SQL运行历史
// dbm.POST("/update_db_manage", UpdateDBManageHandler) // 更新数据库管理信息
export const FindDBManageListService = (Data) => {
const params = new URLSearchParams();
for (let key in Data) {
if(key == "token"){
continue;
}
params.append(key, Data[key])
}
return request.post('/dbm/get_db_manage', params,{
headers: {
'token': Data.token, //token
}
})
}
export const AddDBManageService = (Data) => {
const params = new URLSearchParams();
for (let key in Data) {
if(key == "token"){
continue;
}
params.append(key, Data[key])
}
return request.post('/dbm/create_db_manage', params,{
headers: {
'token': Data.token, //token
}
})
}
export const UpdateDBManageService = (Data) => {
const params = new URLSearchParams();
for (let key in Data) {
if(key == "token"){
continue;
}
params.append(key, Data[key])
}
return request.post('/dbm/update_db_manage', params,{
headers: {
'token': Data.token, //token
}
})
}
export const RunSQLService = (Data) => {
const params = new URLSearchParams();
for (let key in Data) {
if(key == "token"){
continue;
}
params.append(key, Data[key])
}
return request.post('/dbm/run_sql', params,{
headers: {
'token': Data.token, //token
}
})
}
export const GetSQLRunHistoryService = (Data) => {
const params = new URLSearchParams();
for (let key in Data) {
if(key == "token"){
continue;
}
params.append(key, Data[key])
}
return request.post('/dbm/get_sql_history', params,{
headers: {
'token': Data.token, //token
}
})
}

View File

@ -238,6 +238,12 @@ export const menuData: Menus[] = [
index: '/project-select',
title: '项目选择',
},
{
id: '72',
icon: 'ChatDotSquare',
index: '/db-manage',
title: '数据库管理工具',
},
{
id: '6',
icon: 'DocumentAdd',

View File

@ -96,6 +96,16 @@ const routes: RouteRecordRaw[] = [
},
component: () => import(/* webpackChunkName: "project-select" */ '../views/system/project-select.vue'),
},
{
path: '/db-manage',
name: 'db-manage',
meta: {
title: '数据库管理工具',
permiss: '72',
},
component: () => import(/* webpackChunkName: "project-select" */ '../views/system/db-manage.vue'),
},
{
path: '/callback',

View File

@ -57,6 +57,7 @@ export const usePermissStore = defineStore("permiss", {
"58", //知识库管理
"59", //项目选择
"71", //用户功能管理
"72" //数据库管理工具
],
user: ["0", "8", "7", "9", "51" ,"53","55" ,"56", "57", "58", "59", "61", "71"],
},

17
src/types/dbm.ts Normal file
View File

@ -0,0 +1,17 @@
export interface DatabaseConfig {
ID: number;
CreatedAt: string;
UpdatedAt: string;
DeletedAt: null;
UserID: number;
DB_IP: string;
DB_Port: number;
DB_NAME: string;
DB_User: string;
DB_Password: string;
DB_Type: number;
DB_Desc: string;
DB_STATUS: number;
Name: string;
}

93
src/utils/requst_tx_vp.ts Normal file
View File

@ -0,0 +1,93 @@
import axios from "axios";
import router from "@/router/index.js";
import { ElMessage } from 'element-plus';
//const baseURL = "https://gep.ljsea.top/";
const baseURL = "https://tx.ljsea.top/";
//const baseURL= "http://localhost:8084";
//const baseURL="https://pm.ljsea.top";
//const baseURL = "https://gep.ljsea.xyz/";
let isRefreshing = false;
let requests = [];
const request = axios.create({
baseURL: baseURL,
});
// 请求拦截器 - 添加token
request.interceptors.request.use(
config => {
const token = localStorage.getItem("token");
if (token) {
config.headers.Authorization = `Bearer ${token}`;
config.headers.token = token;
}
return config;
}
);
// 响应拦截器
request.interceptors.response.use(
result => {
if(result.status !== 200) {
router.push("/login");
}
if(result.data.message === "NOT_LOGIN" || [2, 3, 4].includes(result.data.code)) {
// 检测到token过期
if (isRefreshing == false) {
isRefreshing = true;
// 这里需要替换为实际的refresh token请求
return axios.post('https://uc.ljsea.top/user/refresh_token', {
refresh_token: localStorage.getItem("refresh_token")
},{
headers: {
'Authorization': `Bearer ${localStorage.getItem("refresh_token")}`
}
}).then(res => {
const token = res.data["data"]["access_token"];
localStorage.setItem("token", token);
//alert("token: " + token);
// 重试所有挂起的请求
requests.forEach(cb => cb(token));
requests = [];
isRefreshing = false;
// 重试当前请求
const config = result.config;
config.headers.Authorization = `Bearer ${token}`;
return request(config);
}).catch(err => {
// 刷新token失败跳转登录
ElMessage.error('登录已过期,请重新登录!');
router.push("/login");
return Promise.reject(err);
});
} else if (isRefreshing) {
// 正在刷新token将请求放入队列
return new Promise(resolve => {
requests.push(token => {
//alert("new token: " + token);
result.config.headers.Authorization = `Bearer ${token}`;
result.config.headers.token = token;
resolve(request(result.config));
});
});
}
}
if(result.data.code == 7) {
ElMessage.error('该用户已存在,请重新输入!');
return null;
}
if(result.data.code == 1) {
ElMessage.error('请求失败,请稍后重试!');
} else {
return result.data;
}
}
);
export default request;

View File

@ -0,0 +1,440 @@
<template>
<div class="db-manage-container">
<el-row :gutter="20">
<!-- 左侧数据库表列表 -->
<el-col :span="4">
<div class="table-list">
<h3>数据库表</h3>
<el-scrollbar height="400px">
<el-tree
:data="tables"
node-key="name"
:props="defaultProps"
@node-click="handleTableClick"
/>
</el-scrollbar>
</div>
</el-col>
<!-- 右侧主内容区 -->
<el-col :span="20">
<!-- 顶部下拉选择框 -->
<el-row :gutter="20" class="mb-20">
<el-col :span="12">
<el-select
v-model="selectedDatabase"
filterable
placeholder="请选择数据库"
class="w-100"
>
<template #prefix>
<el-icon><search /></el-icon>
</template>
<el-option
v-for="item in databases"
:key="item.ID"
:label="item.Name"
:value="item.ID"
>
<span>{{ item.Name }}</span>
<span class="option-actions">
<el-icon @click.stop="editDatabase(item)"><edit /></el-icon>
<el-icon @click.stop="deleteDatabase(item)"><delete /></el-icon>
</span>
</el-option>
<template #append>
<el-button icon="plus" @click="showAddDatabaseDialog" />
</template>
</el-select>
</el-col>
<el-col :span="12">
<el-select
v-model="selectedConnection"
filterable
placeholder="请选择连接"
class="w-100"
>
<template #prefix>
<el-icon><search /></el-icon>
</template>
<el-option
v-for="item in connections"
:key="item.id"
:label="item.name"
:value="item.id"
>
<span>{{ item.name }}</span>
<span class="option-actions">
<el-icon @click.stop="editConnection(item)"><edit /></el-icon>
<el-icon @click.stop="deleteConnection(item)"><delete /></el-icon>
</span>
</el-option>
<template #append>
<el-button icon="plus" @click="showAddConnectionDialog" />
</template>
</el-select>
</el-col>
</el-row>
<!-- SQL输入框和执行按钮 -->
<el-row class="mb-20">
<el-col :span="20">
<el-input
v-model="sqlQuery"
type="textarea"
:rows="3"
placeholder="请输入SQL语句"
/>
</el-col>
<el-col :span="4">
<el-button type="primary" @click="executeSql" class="w-100" :loading="executing">
执行
</el-button>
</el-col>
</el-row>
<!-- 结果表格 -->
<el-table
:data="tableData"
border
style="width: 100%"
height="400px"
v-horizontal-scroll="'always'"
v-loading="loading"
>
<el-table-column
v-for="column in tableColumns"
:key="column.prop"
:prop="column.prop"
:label="column.label"
/>
</el-table>
</el-col>
</el-row>
<!-- 添加/编辑数据库对话框 -->
<el-dialog
v-model="databaseDialogVisible"
:title="isEditDatabase ? '编辑数据库' : '添加数据库'"
width="50%"
:close-on-click-modal="false"
>
<el-form :model="databaseForm" label-width="100px">
<el-form-item label="数据库名称" required>
<el-input v-model="databaseForm.name" placeholder="请输入数据库名称" />
</el-form-item>
</el-form>
<template #footer>
<el-button @click="databaseDialogVisible = false">取消</el-button>
<el-button type="primary" @click="saveDatabase">保存</el-button>
</template>
</el-dialog>
<!-- 添加/编辑连接对话框 -->
<el-dialog
v-model="connectionDialogVisible"
:title="isEditConnection ? '编辑连接' : '添加连接'"
width="50%"
:close-on-click-modal="false"
>
<el-form :model="connectionForm" label-width="100px">
<el-form-item label="连接名称" required>
<el-input v-model="connectionForm.name" placeholder="请输入连接名称" />
</el-form-item>
<el-form-item label="连接地址" required>
<el-input v-model="connectionForm.host" placeholder="请输入连接地址" />
</el-form-item>
<el-form-item label="端口" required>
<el-input v-model="connectionForm.port" placeholder="请输入端口" />
</el-form-item>
<el-form-item label="用户名" required>
<el-input v-model="connectionForm.username" placeholder="请输入用户名" />
</el-form-item>
<el-form-item label="密码" required>
<el-input v-model="connectionForm.password" type="password" placeholder="请输入密码" />
</el-form-item>
</el-form>
<template #footer>
<el-button @click="connectionDialogVisible = false">取消</el-button>
<el-button type="primary" @click="saveConnection">保存</el-button>
</template>
</el-dialog>
</div>
</template>
<script lang="ts">
import { defineComponent, ref, reactive } from 'vue';
import {FindDBManageListService,AddDBManageService,UpdateDBManageService,RunSQLService,GetSQLRunHistoryService } from '@/api/dbm';
import {DatabaseConfig} from '@/types/dbm';
import horizontalScroll from 'el-table-horizontal-scroll'
import {
Search, Edit, Delete, Plus
} from '@element-plus/icons-vue';
export default defineComponent({
name: 'DbManage',
components: {
Search, Edit, Delete, Plus,horizontalScroll
},
setup() {
//
const databases = ref<DatabaseConfig[]>([]);
const selectedDatabase = ref('');
//
const connections = ref([
{ id: 1, name: '本地开发环境' },
{ id: 2, name: '测试环境' },
{ id: 3, name: '生产环境' },
]);
const selectedConnection = ref('');
// SQL
const sqlQuery = ref('');
const executing = ref(false);
const tableData = ref([]);
const tableColumns = ref([]);
const loading = ref(false);
//
const tables = ref([
{ name: 'users', children: [{ name: 'id' }, { name: 'username' }, { name: 'email' }] },
{ name: 'products', children: [{ name: 'id' }, { name: 'name' }, { name: 'price' }] },
]);
const defaultProps = {
children: 'children',
label: 'name',
};
//
const databaseDialogVisible = ref(false);
const isEditDatabase = ref(false);
const databaseForm = reactive({
id: 0,
name: '',
});
//
const connectionDialogVisible = ref(false);
const isEditConnection = ref(false);
const connectionForm = reactive({
id: 0,
name: '',
host: '',
port: '',
username: '',
password: '',
});
//
const showAddDatabaseDialog = () => {
isEditDatabase.value = false;
databaseForm.id = 0;
databaseForm.name = '';
databaseDialogVisible.value = true;
};
const editDatabase = (item) => {
isEditDatabase.value = true;
databaseForm.id = item.id;
databaseForm.name = item.name;
databaseDialogVisible.value = true;
};
const GetDBManageList = async () => {
let req = {"get_type":0, "token":localStorage.getItem("token"), "id":localStorage.getItem("userId")}
await FindDBManageListService(req).then((res: any) => {
if (res.code === 0) {
databases.value = res.data;
for (let i = 0; i < databases.value.length; i++) {
let type = "MySQL";
switch(databases.value[i].DB_Type) {
case 0:
type = "MySQL";
break;
case 1:
type = "PostgreSQL";
break;
}
databases.value[i].Name = type + " - "+ databases.value[i].DB_IP + ":" + databases.value[i].DB_Port + " - " + databases.value[i].DB_NAME;
}
} else {
console.error('获取数据库列表失败:', res.message);
}
}).catch((error: any) => {
console.error('请求错误:', error);
});
};
GetDBManageList();
const deleteDatabase = (item) => {
// API
databases.value = databases.value.filter(db => db.ID !== item.id);
};
const saveDatabase = () => {
if (isEditDatabase.value) {
//
const index = databases.value.findIndex(db => db.ID === databaseForm.id);
if (index !== -1) {
databases.value[index].Name = databaseForm.name;
}
} else {
//
// databases.value.push({
// id: databases.value.length + 1,
// name: databaseForm.name,
// });
}
databaseDialogVisible.value = false;
};
const showAddConnectionDialog = () => {
isEditConnection.value = false;
connectionForm.id = 0;
connectionForm.name = '';
connectionForm.host = '';
connectionForm.port = '';
connectionForm.username = '';
connectionForm.password = '';
connectionDialogVisible.value = true;
};
const editConnection = (item) => {
isEditConnection.value = true;
connectionForm.id = item.id;
connectionForm.name = item.name;
connectionForm.host = item.host || '';
connectionForm.port = item.port || '';
connectionForm.username = item.username || '';
connectionForm.password = item.password || '';
connectionDialogVisible.value = true;
};
const deleteConnection = (item) => {
// API
connections.value = connections.value.filter(conn => conn.id !== item.id);
};
const saveConnection = () => {
if (isEditConnection.value) {
//
const index = connections.value.findIndex(conn => conn.id === connectionForm.id);
if (index !== -1) {
connections.value[index] = { ...connectionForm };
}
} else {
//
connections.value.push({
id: connections.value.length + 1,
...connectionForm,
});
}
connectionDialogVisible.value = false;
};
const executeSql = () => {
executing.value = true;
loading.value = true;
let req = {
"token":localStorage.getItem("token"),
"id":localStorage.getItem("userId"),
"sql":sqlQuery.value,
"db_id":selectedDatabase.value,
};
try{
RunSQLService(req).then((res: any) => {
if (res.code === 0) {
tableData.value = res.data;
// tableColumns.value = res.columns;
let first = res.data[0];
let keys = Object.keys(first);
tableColumns.value = keys.map((key) => {
return { prop: key, label: key };
});
console.log(res.data);
} else {
console.error('执行SQL失败:', res.message);
}
}).catch((error: any) => {
console.error('请求错误:', error);
});
} catch (e) {
console.log(e);
}
executing.value = false;
loading.value = false;
};
const handleTableClick = (data) => {
//
if (!data.children) {
sqlQuery.value = `SELECT * FROM ${data.name}`;
}
};
return {
databases,
selectedDatabase,
connections,
selectedConnection,
sqlQuery,
executing,
tableData,
tableColumns,
loading,
tables,
defaultProps,
databaseDialogVisible,
isEditDatabase,
databaseForm,
connectionDialogVisible,
isEditConnection,
connectionForm,
showAddDatabaseDialog,
editDatabase,
deleteDatabase,
saveDatabase,
showAddConnectionDialog,
editConnection,
deleteConnection,
saveConnection,
executeSql,
handleTableClick,
};
},
});
</script>
<style scoped>
.db-manage-container {
padding: 20px;
}
.table-list {
background: #fff;
padding: 10px;
border-radius: 4px;
box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
}
.mb-20 {
margin-bottom: 20px;
}
.w-100 {
width: 100%;
}
.option-actions {
float: right;
}
.option-actions .el-icon {
margin-left: 10px;
cursor: pointer;
}
</style>

148
yarn.lock
View File

@ -28,7 +28,7 @@
resolved "https://registry.npmjs.org/@antfu/utils/-/utils-8.1.1.tgz"
integrity sha512-Mex9nXf9vR6AhcXmMrlz/HVgYYZpVGJ6YlPgwl7UnaFpnshXs6EK/oa5Gpf3CzENMjkvEx2tQtntGnb7UtSTOQ==
"@babel/parser@^7.15.8", "@babel/parser@^7.23.9":
"@babel/parser@^7.15.8", "@babel/parser@^7.23.5", "@babel/parser@^7.23.9":
version "7.24.4"
resolved "https://registry.npmjs.org/@babel/parser/-/parser-7.24.4.tgz"
integrity sha512-zTvEBcghmeBma9QIGunWevvBAp4/Qu9Bdq+2k0Ot4fVMD6v3dsC9WOcRSKk7tRRyBM/53yKMJko9xOatGQAwSg==
@ -835,6 +835,17 @@
postcss "^8.4.35"
source-map-js "^1.0.2"
"@vue/compiler-sfc@2.7.16":
version "2.7.16"
resolved "https://registry.npmjs.org/@vue/compiler-sfc/-/compiler-sfc-2.7.16.tgz"
integrity sha512-KWhJ9k5nXuNtygPU7+t1rX6baZeqOYLEforUPjgNDBnLicfHCoi48H87Q8XyLZOrNNsmhuwKqtpDQWjEFe6Ekg==
dependencies:
"@babel/parser" "^7.23.5"
postcss "^8.4.14"
source-map "^0.6.1"
optionalDependencies:
prettier "^1.18.2 || ^2.0.0"
"@vue/compiler-ssr@3.4.21":
version "3.4.21"
resolved "https://registry.npmjs.org/@vue/compiler-ssr/-/compiler-ssr-3.4.21.tgz"
@ -1040,6 +1051,13 @@ async-validator@^4.2.5:
resolved "https://registry.npmjs.org/async-validator/-/async-validator-4.2.5.tgz"
integrity sha512-7HhHjtERjqlNbZtqNqy2rckN/SpOOlmDliet+lP7k+eKZEjPk3DgyeU9lIXLdeLz0uBbbVp+9Qdow9wJWgwwfg==
async-validator@~1.8.1:
version "1.8.5"
resolved "https://registry.npmjs.org/async-validator/-/async-validator-1.8.5.tgz"
integrity sha512-tXBM+1m056MAX0E8TL2iCjg8WvSyXu0Zc8LNtYqrVeyoL3+esHRZ4SieE9fKQyyU09uONjnMEjrNBMqT0mbvmA==
dependencies:
babel-runtime "6.x"
asynckit@^0.4.0:
version "0.4.0"
resolved "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz"
@ -1054,6 +1072,19 @@ axios@^1.6.3:
form-data "^4.0.0"
proxy-from-env "^1.1.0"
babel-helper-vue-jsx-merge-props@^2.0.0:
version "2.0.3"
resolved "https://registry.npmjs.org/babel-helper-vue-jsx-merge-props/-/babel-helper-vue-jsx-merge-props-2.0.3.tgz"
integrity sha512-gsLiKK7Qrb7zYJNgiXKpXblxbV5ffSwR0f5whkPAaBAR4fhi6bwRZxX9wBlIc5M/v8CCkXUbXZL4N/nSE97cqg==
babel-runtime@6.x:
version "6.26.0"
resolved "https://registry.npmjs.org/babel-runtime/-/babel-runtime-6.26.0.tgz"
integrity sha512-ITKNuq2wKlW1fJg9sSW52eepoYgZBggvOAHC0u/CYu/qxQ9EVzThCgR69BnSXLHjy2f7SY5zaQ4yt7H9ZVxY2g==
dependencies:
core-js "^2.4.0"
regenerator-runtime "^0.11.0"
balanced-match@^1.0.0:
version "1.0.2"
resolved "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz"
@ -1224,6 +1255,16 @@ config-chain@^1.1.13:
ini "^1.3.4"
proto-list "~1.2.1"
core-js@^2.4.0:
version "2.6.12"
resolved "https://registry.npmjs.org/core-js/-/core-js-2.6.12.tgz"
integrity sha512-Kb2wC0fvsWfQrgk8HU5lW6U/Lcs8+9aaYcy4ZFc6DDlo4nZ7n70dEgE5rtR0oG6ufKDUnrwfWL1mXR5ljDatrQ==
core-js@^3.6.5:
version "3.45.0"
resolved "https://registry.npmjs.org/core-js/-/core-js-3.45.0.tgz"
integrity sha512-c2KZL9lP4DjkN3hk/an4pWn5b5ZefhRJnAc42n6LJ19kSnbeRbdQZE5dSeE2LBol1OwJD3X1BQvFTAsa8ReeDA==
cose-base@^1.0.0:
version "1.0.3"
resolved "https://registry.npmjs.org/cose-base/-/cose-base-1.0.3.tgz"
@ -1280,7 +1321,7 @@ cssfilter@0.0.10:
resolved "https://registry.npmjs.org/cssfilter/-/cssfilter-0.0.10.tgz"
integrity sha512-FAaLDaplstoRsDR8XGYH51znUN0UY7nMc6Z9/fvE8EXGwvJE9hu7W2vHwx1+bd6gCYnln9nLbzxFTrcO9YQDZw==
csstype@^3.1.3:
csstype@^3.1.0, csstype@^3.1.3:
version "3.1.3"
resolved "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz"
integrity sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==
@ -1649,6 +1690,11 @@ decode-named-character-reference@^1.0.0:
dependencies:
character-entities "^2.0.0"
deepmerge@^1.2.0:
version "1.5.2"
resolved "https://registry.npmjs.org/deepmerge/-/deepmerge-1.5.2.tgz"
integrity sha512-95k0GDqvBjZavkuvzx/YqVLv/6YYa17fz6ILMSf7neqQITCPbnfEnQvEgMPNjH4kgobe7+WIL0yJEHku+H3qtQ==
delaunator@5:
version "5.0.1"
resolved "https://registry.npmjs.org/delaunator/-/delaunator-5.0.1.tgz"
@ -1733,6 +1779,19 @@ editorconfig@^1.0.4:
minimatch "9.0.1"
semver "^7.5.3"
el-table-horizontal-scroll@^1.2.5:
version "1.2.5"
resolved "https://registry.npmjs.org/el-table-horizontal-scroll/-/el-table-horizontal-scroll-1.2.5.tgz"
integrity sha512-2Ays+8skp64Yl5YE2Kpa/9lJ720jPn1ooNSc2LKiF0ECiXPEoBZ5hhd144Inp1JATs5of4YzNwNd9L/Xy397GQ==
dependencies:
core-js "^3.6.5"
element-ui "^2.15.6"
lodash "^4.17.21"
throttle-debounce "^5.0.0"
vue "^2.6.11"
vue-route "^1.5.1"
vue-router "^3.5.3"
element-plus@^2.6.3:
version "2.7.0"
resolved "https://registry.npmjs.org/element-plus/-/element-plus-2.7.0.tgz"
@ -1754,6 +1813,18 @@ element-plus@^2.6.3:
memoize-one "^6.0.0"
normalize-wheel-es "^1.2.0"
element-ui@^2.15.6:
version "2.15.14"
resolved "https://registry.npmjs.org/element-ui/-/element-ui-2.15.14.tgz"
integrity sha512-2v9fHL0ZGINotOlRIAJD5YuVB8V7WKxrE9Qy7dXhRipa035+kF7WuU/z+tEmLVPBcJ0zt8mOu1DKpWcVzBK8IA==
dependencies:
async-validator "~1.8.1"
babel-helper-vue-jsx-merge-props "^2.0.0"
deepmerge "^1.2.0"
normalize-wheel "^1.0.1"
resize-observer-polyfill "^1.5.0"
throttle-debounce "^1.0.1"
elkjs@^0.8.2:
version "0.8.2"
resolved "https://registry.npmjs.org/elkjs/-/elkjs-0.8.2.tgz"
@ -2103,6 +2174,11 @@ is-url@^1.2.4:
resolved "https://registry.npmjs.org/is-url/-/is-url-1.2.4.tgz"
integrity sha512-ITvGim8FhRiYe4IQ5uHSkj7pVaPDrCTkNd3yq3cV7iZAcJdHTUMPMEHcqSOy9xZ9qFenQCvi+2wjH9a1nXqHww==
isarray@0.0.1:
version "0.0.1"
resolved "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz"
integrity sha512-D2S+3GLxWH+uhrNEcoh/fnmYeP8E8/zHl644d/jdA0g2uyXvy3sb0qxotE+ne0LtccHknQzWwZEzhak7oJ0COQ==
isexe@^2.0.0:
version "2.0.0"
resolved "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz"
@ -2841,6 +2917,11 @@ normalize-wheel-es@^1.2.0:
resolved "https://registry.npmjs.org/normalize-wheel-es/-/normalize-wheel-es-1.2.0.tgz"
integrity sha512-Wj7+EJQ8mSuXr2iWfnujrimU35R2W4FAErEyTmJoJ7ucwTn2hOUSsRehMb5RSYkxXGTM7Y9QpvPmp++w5ftoJw==
normalize-wheel@^1.0.1:
version "1.0.1"
resolved "https://registry.npmjs.org/normalize-wheel/-/normalize-wheel-1.0.1.tgz"
integrity sha512-1OnlAPZ3zgrk8B91HyRj+eVv+kS5u+Z0SCsak6Xil/kmgEia50ga7zfkumayonZrImffAxPU/5WcyGhzetHNPA==
nprogress@^0.2.0:
version "0.2.0"
resolved "https://registry.npmjs.org/nprogress/-/nprogress-0.2.0.tgz"
@ -2858,6 +2939,13 @@ package-manager-detector@^0.2.8:
dependencies:
quansync "^0.2.7"
page@^1.5.0:
version "1.11.6"
resolved "https://registry.npmjs.org/page/-/page-1.11.6.tgz"
integrity sha512-P6e2JfzkBrPeFCIPplLP7vDDiU84RUUZMrWdsH4ZBGJ8OosnwFkcUkBHp1DTIjuipLliw9yQn/ZJsXZvarsO+g==
dependencies:
path-to-regexp "~1.2.1"
path-data-parser@^0.1.0, path-data-parser@0.1.0:
version "0.1.0"
resolved "https://registry.npmjs.org/path-data-parser/-/path-data-parser-0.1.0.tgz"
@ -2881,6 +2969,13 @@ path-scurry@^1.11.1:
lru-cache "^10.2.0"
minipass "^5.0.0 || ^6.0.2 || ^7.0.0"
path-to-regexp@~1.2.1:
version "1.2.1"
resolved "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-1.2.1.tgz"
integrity sha512-DBw9IhWfevR2zCVwEZURTuQNseCvu/Q9f5ZgqMCK0Rh61bDa4uyjPAOy9b55yKiPT59zZn+7uYKxmWwsguInwg==
dependencies:
isarray "0.0.1"
pathe@^1.0.0, pathe@^1.1.0:
version "1.1.2"
resolved "https://registry.npmjs.org/pathe/-/pathe-1.1.2.tgz"
@ -2954,7 +3049,7 @@ points-on-path@^0.2.1:
path-data-parser "0.1.0"
points-on-curve "0.2.0"
postcss@^8.4.18, postcss@^8.4.35:
postcss@^8.4.14, postcss@^8.4.18, postcss@^8.4.35:
version "8.4.38"
resolved "https://registry.npmjs.org/postcss/-/postcss-8.4.38.tgz"
integrity sha512-Wglpdk03BSfXkHoQa3b/oulrotAkwrlLDRSOb9D0bN86FdRyE9lppSp33aHNPgBa0JKCoB+drFLZkQoRRYae5A==
@ -2968,6 +3063,11 @@ preact@^10.5.13:
resolved "https://registry.npmjs.org/preact/-/preact-10.20.2.tgz"
integrity sha512-S1d1ernz3KQ+Y2awUxKakpfOg2CEmJmwOP+6igPx6dgr6pgDvenqYviyokWso2rhHvGtTlWWnJDa7RaPbQerTg==
"prettier@^1.18.2 || ^2.0.0":
version "2.8.8"
resolved "https://registry.npmjs.org/prettier/-/prettier-2.8.8.tgz"
integrity sha512-tdN8qQGvNjw4CHbY+XXk0JgCXn9QiF21a55rBe5LJAU+kDyC4WQn4+awm2Xfk2lQMk5fKup9XgzTZtGkjBdP9Q==
prismjs@^1.23.0:
version "1.29.0"
resolved "https://registry.npmjs.org/prismjs/-/prismjs-1.29.0.tgz"
@ -3005,6 +3105,11 @@ readdirp@~3.6.0:
dependencies:
picomatch "^2.2.1"
regenerator-runtime@^0.11.0:
version "0.11.1"
resolved "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.11.1.tgz"
integrity sha512-MguG95oij0fC3QV3URf4V2SDYGJhJnJGqvIIgdECeODCT98wSWDAJ94SSuVpYQUoTcGUIL6L4yNB7j1DFFHSBg==
regenerator-runtime@^0.14.0:
version "0.14.1"
resolved "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.14.1.tgz"
@ -3015,6 +3120,11 @@ resize-detector@^0.3.0:
resolved "https://registry.npmjs.org/resize-detector/-/resize-detector-0.3.0.tgz"
integrity sha512-R/tCuvuOHQ8o2boRP6vgx8hXCCy87H1eY9V5imBYeVNyNVpuL9ciReSccLj2gDcax9+2weXy3bc8Vv+NRXeEvQ==
resize-observer-polyfill@^1.5.0:
version "1.5.1"
resolved "https://registry.npmjs.org/resize-observer-polyfill/-/resize-observer-polyfill-1.5.1.tgz"
integrity sha512-LwZrotdHOo12nQuZlHEmtuXdqGoOD0OhaxopaNFxWzInpEgaLWoVuAMbTzixuosCx2nEG58ngzW3vxdWoxIgdg==
resolve@^1.22.1:
version "1.22.8"
resolved "https://registry.npmjs.org/resolve/-/resolve-1.22.8.tgz"
@ -3153,7 +3263,7 @@ source-map-support@~0.5.20:
buffer-from "^1.0.0"
source-map "^0.6.0"
source-map@^0.6.0:
source-map@^0.6.0, source-map@^0.6.1:
version "0.6.1"
resolved "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz"
integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==
@ -3255,6 +3365,16 @@ terser@^5.22.0, terser@^5.4.0:
commander "^2.20.0"
source-map-support "~0.5.20"
throttle-debounce@^1.0.1:
version "1.1.0"
resolved "https://registry.npmjs.org/throttle-debounce/-/throttle-debounce-1.1.0.tgz"
integrity sha512-XH8UiPCQcWNuk2LYePibW/4qL97+ZQ1AN3FNXwZRBNPPowo/NRU5fAlDCSNBJIYCKbioZfuYtMhG4quqoJhVzg==
throttle-debounce@^5.0.0:
version "5.0.2"
resolved "https://registry.npmjs.org/throttle-debounce/-/throttle-debounce-5.0.2.tgz"
integrity sha512-B71/4oyj61iNH0KeCamLuE2rmKuTO5byTOSVwECM5FA7TiAiAW+UqTKZ9ERueC4qvgSttUhdmq1mXC3kJqGX7A==
tiny-emitter@^2.0.0:
version "2.1.0"
resolved "https://registry.npmjs.org/tiny-emitter/-/tiny-emitter-2.1.0.tgz"
@ -3506,6 +3626,18 @@ vue-echarts@^6.6.9:
resize-detector "^0.3.0"
vue-demi "^0.13.11"
vue-route@^1.5.1:
version "1.5.1"
resolved "https://registry.npmjs.org/vue-route/-/vue-route-1.5.1.tgz"
integrity sha512-RoeEWvSTk/Zasjx11En4XPyE1jXwuFQ4Itr4fzh1TOSMYefUddhhlHXmAGFFPn37J1YrEymm6sU/3IRTyu23Aw==
dependencies:
page "^1.5.0"
vue-router@^3.5.3:
version "3.6.5"
resolved "https://registry.npmjs.org/vue-router/-/vue-router-3.6.5.tgz"
integrity sha512-VYXZQLtjuvKxxcshuRAwjHnciqZVoXAjTjcqBTz4rKc8qih9g9pI3hbDjmqXaHdgL3v8pV6P8Z335XvHzESxLQ==
vue-router@^4.2.5:
version "4.3.0"
resolved "https://registry.npmjs.org/vue-router/-/vue-router-4.3.0.tgz"
@ -3538,6 +3670,14 @@ vue@*, "vue@^2.6.12 || ^3.1.1", "vue@^2.6.14 || ^3.3.0", "vue@^3.0.0-0 || ^2.6.0
"@vue/server-renderer" "3.4.21"
"@vue/shared" "3.4.21"
vue@^2.5.17, vue@^2.6.11:
version "2.7.16"
resolved "https://registry.npmjs.org/vue/-/vue-2.7.16.tgz"
integrity sha512-4gCtFXaAA3zYZdTp5s4Hl2sozuySsgz4jy1EnpBHNfpMa9dK1ZCG7viqBPCwXtmgc8nHqUsAu3G4gtmXkkY3Sw==
dependencies:
"@vue/compiler-sfc" "2.7.16"
csstype "^3.1.0"
w3c-keyname@^2.2.4:
version "2.2.8"
resolved "https://registry.npmjs.org/w3c-keyname/-/w3c-keyname-2.2.8.tgz"