mirror of
https://gitee.com/dromara/mayfly-go
synced 2025-11-02 23:40:24 +08:00
feat: DBMS 数据库管理、redis管理、mongo管理,新增【数据操作】快捷跳转
This commit is contained in:
@@ -5,6 +5,9 @@ import themeConfig from '@/store/modules/themeConfig.ts';
|
|||||||
import routesList from '@/store/modules/routesList.ts';
|
import routesList from '@/store/modules/routesList.ts';
|
||||||
import keepAliveNames from '@/store/modules/keepAliveNames.ts';
|
import keepAliveNames from '@/store/modules/keepAliveNames.ts';
|
||||||
import userInfos from '@/store/modules/userInfos.ts';
|
import userInfos from '@/store/modules/userInfos.ts';
|
||||||
|
import sqlExecInfo from '@/store/modules/mysqlDbOptInfo.ts';
|
||||||
|
import redisDbOptInfo from '@/store/modules/redisDbOptInfo.ts';
|
||||||
|
import mongoDbOptInfo from '@/store/modules/mongoDbOptInfo.ts';
|
||||||
|
|
||||||
export const key: InjectionKey<Store<RootStateTypes>> = Symbol();
|
export const key: InjectionKey<Store<RootStateTypes>> = Symbol();
|
||||||
|
|
||||||
@@ -14,6 +17,9 @@ export const store = createStore<RootStateTypes>({
|
|||||||
routesList,
|
routesList,
|
||||||
keepAliveNames,
|
keepAliveNames,
|
||||||
userInfos,
|
userInfos,
|
||||||
|
sqlExecInfo,
|
||||||
|
redisDbOptInfo,
|
||||||
|
mongoDbOptInfo,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -71,6 +71,16 @@ export interface UserInfosState {
|
|||||||
userInfos: object;
|
userInfos: object;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 数据操作信息
|
||||||
|
export interface DbOptInfoState {
|
||||||
|
dbOptInfo: {
|
||||||
|
projectId?: number,
|
||||||
|
envId?: number,
|
||||||
|
dbId?: number,
|
||||||
|
db?: string,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// 后端返回原始路由(未处理时)
|
// 后端返回原始路由(未处理时)
|
||||||
// export interface RequestOldRoutesState {
|
// export interface RequestOldRoutesState {
|
||||||
// requestOldRoutes: Array<object>;
|
// requestOldRoutes: Array<object>;
|
||||||
@@ -82,5 +92,8 @@ export interface RootStateTypes {
|
|||||||
routesList: RoutesListState;
|
routesList: RoutesListState;
|
||||||
keepAliveNames: KeepAliveNamesState;
|
keepAliveNames: KeepAliveNamesState;
|
||||||
userInfos: UserInfosState;
|
userInfos: UserInfosState;
|
||||||
|
sqlExecInfo: DbOptInfoState;
|
||||||
|
redisDbOptInfo: DbOptInfoState;
|
||||||
|
mongoDbOptInfo: DbOptInfoState;
|
||||||
// requestOldRoutes: RequestOldRoutesState;
|
// requestOldRoutes: RequestOldRoutesState;
|
||||||
}
|
}
|
||||||
|
|||||||
31
mayfly_go_web/src/store/modules/mongoDbOptInfo.ts
Normal file
31
mayfly_go_web/src/store/modules/mongoDbOptInfo.ts
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
import { Module } from 'vuex';
|
||||||
|
// 此处加上 `.ts` 后缀报错,具体原因不详
|
||||||
|
import {DbOptInfoState, RootStateTypes} from '@/store/interface';
|
||||||
|
|
||||||
|
const mongoDbOptInfoModule: Module<DbOptInfoState, RootStateTypes> = {
|
||||||
|
namespaced: true,
|
||||||
|
state: {
|
||||||
|
dbOptInfo: {
|
||||||
|
projectId: 0,
|
||||||
|
envId: 0,
|
||||||
|
dbId: 0,
|
||||||
|
db: '0',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
mutations: {
|
||||||
|
// 设置用户信息
|
||||||
|
getMongoDbOptInfo(state: any, data: object) {
|
||||||
|
state.dbOptInfo = data;
|
||||||
|
},
|
||||||
|
},
|
||||||
|
actions: {
|
||||||
|
// 设置用户信息
|
||||||
|
async setMongoDbOptInfo({ commit }, data: object) {
|
||||||
|
if (data) {
|
||||||
|
commit('getMongoDbOptInfo', data);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
export default mongoDbOptInfoModule;
|
||||||
31
mayfly_go_web/src/store/modules/mysqlDbOptInfo.ts
Normal file
31
mayfly_go_web/src/store/modules/mysqlDbOptInfo.ts
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
import { Module } from 'vuex';
|
||||||
|
// 此处加上 `.ts` 后缀报错,具体原因不详
|
||||||
|
import { DbOptInfoState, RootStateTypes } from '@/store/interface';
|
||||||
|
|
||||||
|
const sqlExecInfoModule: Module<DbOptInfoState, RootStateTypes> = {
|
||||||
|
namespaced: true,
|
||||||
|
state: {
|
||||||
|
dbOptInfo: {
|
||||||
|
projectId: 0,
|
||||||
|
envId: 0,
|
||||||
|
dbId: 0,
|
||||||
|
db: '0',
|
||||||
|
}
|
||||||
|
},
|
||||||
|
mutations: {
|
||||||
|
// 设置用户信息
|
||||||
|
getSqlExecInfo(state: any, data: object) {
|
||||||
|
state.dbOptInfo = data;
|
||||||
|
},
|
||||||
|
},
|
||||||
|
actions: {
|
||||||
|
// 设置用户信息
|
||||||
|
async setSqlExecInfo({ commit }, data: object) {
|
||||||
|
if (data) {
|
||||||
|
commit('getSqlExecInfo', data);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
export default sqlExecInfoModule;
|
||||||
31
mayfly_go_web/src/store/modules/redisDbOptInfo.ts
Normal file
31
mayfly_go_web/src/store/modules/redisDbOptInfo.ts
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
import { Module } from 'vuex';
|
||||||
|
// 此处加上 `.ts` 后缀报错,具体原因不详
|
||||||
|
import {DbOptInfoState, RootStateTypes} from '@/store/interface';
|
||||||
|
|
||||||
|
const redisDbOptInfoModule: Module<DbOptInfoState, RootStateTypes> = {
|
||||||
|
namespaced: true,
|
||||||
|
state: {
|
||||||
|
dbOptInfo: {
|
||||||
|
projectId: 0,
|
||||||
|
envId: 0,
|
||||||
|
dbId: 0,
|
||||||
|
db: '0',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
mutations: {
|
||||||
|
// 设置用户信息
|
||||||
|
getRedisDbOptInfo(state: any, data: object) {
|
||||||
|
state.dbOptInfo = data;
|
||||||
|
},
|
||||||
|
},
|
||||||
|
actions: {
|
||||||
|
// 设置用户信息
|
||||||
|
async setRedisDbOptInfo({ commit }, data: object) {
|
||||||
|
if (data) {
|
||||||
|
commit('getRedisDbOptInfo', data);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
export default redisDbOptInfoModule;
|
||||||
@@ -22,7 +22,7 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { toRefs, reactive, defineComponent, onMounted } from 'vue';
|
import {toRefs, reactive, defineComponent, onMounted, watch} from 'vue';
|
||||||
import { projectApi } from '../project/api';
|
import { projectApi } from '../project/api';
|
||||||
|
|
||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
@@ -52,8 +52,27 @@ export default defineComponent({
|
|||||||
envId: null,
|
envId: null,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// 动态选中项目和环境
|
||||||
|
const setData = async (projectId: null, envId: null) => {
|
||||||
|
if (projectId) {
|
||||||
|
state.projectId = projectId;
|
||||||
|
if (envId) {
|
||||||
|
state.envs = await projectApi.projectEnvs.request({projectId});
|
||||||
|
state.envId = envId;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
watch(() => props.data, (newValue)=>{
|
||||||
|
setData(newValue.projectId, newValue.envId)
|
||||||
|
})
|
||||||
|
|
||||||
onMounted(async () => {
|
onMounted(async () => {
|
||||||
state.projects = await projectApi.accountProjects.request(null);
|
state.projects = await projectApi.accountProjects.request(null);
|
||||||
|
// 初始化容器时可能会选中项目和环境
|
||||||
|
if(props.data?.projectId && props.data?.envId){
|
||||||
|
await setData(props.data.projectId, props.data.envId)
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
const changeProject = async (projectId: any) => {
|
const changeProject = async (projectId: any) => {
|
||||||
@@ -72,6 +91,7 @@ export default defineComponent({
|
|||||||
...toRefs(state),
|
...toRefs(state),
|
||||||
changeProject,
|
changeProject,
|
||||||
changeEnv,
|
changeEnv,
|
||||||
|
setData,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -31,20 +31,22 @@
|
|||||||
<el-table-column prop="type" label="类型" min-width="90"></el-table-column>
|
<el-table-column prop="type" label="类型" min-width="90"></el-table-column>
|
||||||
<el-table-column prop="database" label="数据库" min-width="80">
|
<el-table-column prop="database" label="数据库" min-width="80">
|
||||||
<template #default="scope">
|
<template #default="scope">
|
||||||
<el-popover :width="250" placement="right" trigger="click">
|
<el-popover placement="right" trigger="click" :width="300">
|
||||||
<template #reference>
|
<template #reference>
|
||||||
<el-link type="primary" :underline="false" plain>查看</el-link>
|
<el-link type="primary" :underline="false" plain @click="selectDb(scope.row.dbs)">查看</el-link>
|
||||||
</template>
|
</template>
|
||||||
<el-tag
|
<el-input v-model="filterDb.param" @keyup="filterSchema" class="w-50 m-2" placeholder="搜索" size="small" >
|
||||||
@click="showTableInfo(scope.row, db)"
|
<template #prefix>
|
||||||
effect="plain"
|
<el-icon class="el-input__icon"><search-icon /></el-icon>
|
||||||
type="success"
|
</template>
|
||||||
size="small"
|
</el-input>
|
||||||
v-for="db in scope.row.dbs"
|
<div class="el-tag--plain el-tag--success"
|
||||||
:key="db"
|
v-for="db in filterDb.list" :key="db"
|
||||||
style="cursor: pointer; margin-left: 3px; margin-bottom: 3px;"
|
style="border:1px var(--color-success-light-3) solid; margin-top: 3px;border-radius: 5px; padding: 2px;position: relative"
|
||||||
>{{ db }}</el-tag
|
|
||||||
>
|
>
|
||||||
|
<el-link type="success" plain size="small" :underline="false" @click="showTableInfo(scope.row, db)">{{ db }}</el-link>
|
||||||
|
<el-link type="primary" plain size="small" :underline="false" @click="openSqlExec(scope.row, db)" style="position: absolute; right: 4px">数据操作</el-link>
|
||||||
|
</div>
|
||||||
</el-popover>
|
</el-popover>
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
@@ -271,15 +273,20 @@ import SqlExecBox from './component/SqlExecBox.ts';
|
|||||||
import config from '@/common/config';
|
import config from '@/common/config';
|
||||||
import { getSession } from '@/common/utils/storage';
|
import { getSession } from '@/common/utils/storage';
|
||||||
import { isTrue } from '@/common/assert';
|
import { isTrue } from '@/common/assert';
|
||||||
|
import { Search as SearchIcon } from '@element-plus/icons-vue'
|
||||||
|
import router from '@/router';
|
||||||
|
import {store} from '@/store';
|
||||||
|
|
||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
name: 'DbList',
|
name: 'DbList',
|
||||||
components: {
|
components: {
|
||||||
DbEdit,
|
DbEdit,
|
||||||
CreateTable,
|
CreateTable,
|
||||||
|
SearchIcon,
|
||||||
},
|
},
|
||||||
setup() {
|
setup() {
|
||||||
const state = reactive({
|
const state = reactive({
|
||||||
|
row: {},
|
||||||
dbId: 0,
|
dbId: 0,
|
||||||
db: '',
|
db: '',
|
||||||
permissions: {
|
permissions: {
|
||||||
@@ -296,6 +303,7 @@ export default defineComponent({
|
|||||||
* 查询条件
|
* 查询条件
|
||||||
*/
|
*/
|
||||||
query: {
|
query: {
|
||||||
|
projectId:null,
|
||||||
pageNum: 1,
|
pageNum: 1,
|
||||||
pageSize: 10,
|
pageSize: 10,
|
||||||
},
|
},
|
||||||
@@ -356,6 +364,11 @@ export default defineComponent({
|
|||||||
tableCreateDialog: {
|
tableCreateDialog: {
|
||||||
visible: false,
|
visible: false,
|
||||||
},
|
},
|
||||||
|
filterDb:{
|
||||||
|
param:'',
|
||||||
|
cache:[],
|
||||||
|
list:[],
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
onMounted(async () => {
|
onMounted(async () => {
|
||||||
@@ -545,6 +558,7 @@ export default defineComponent({
|
|||||||
try {
|
try {
|
||||||
state.tableInfoDialog.infos = await dbApi.tableInfos.request({ id: row.id, db });
|
state.tableInfoDialog.infos = await dbApi.tableInfos.request({ id: row.id, db });
|
||||||
state.dbId = row.id;
|
state.dbId = row.id;
|
||||||
|
state.row = row;
|
||||||
state.db = db;
|
state.db = db;
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
state.tableInfoDialog.visible = false;
|
state.tableInfoDialog.visible = false;
|
||||||
@@ -613,6 +627,37 @@ export default defineComponent({
|
|||||||
});
|
});
|
||||||
} catch (err) {}
|
} catch (err) {}
|
||||||
};
|
};
|
||||||
|
const openSqlExec = (row: any, db: any) => {
|
||||||
|
// 判断db是否发生改变
|
||||||
|
let oldDb = store.state.sqlExecInfo.dbOptInfo.db;
|
||||||
|
if(db && oldDb !== db){
|
||||||
|
const {projectId, envId, id} = row;
|
||||||
|
let params = {
|
||||||
|
projectId,
|
||||||
|
envId,
|
||||||
|
dbId: id,
|
||||||
|
db
|
||||||
|
}
|
||||||
|
store.dispatch('sqlExecInfo/setSqlExecInfo', params);
|
||||||
|
}
|
||||||
|
router.push({name: 'SqlExec'});
|
||||||
|
}
|
||||||
|
|
||||||
|
// 点击查看时初始化数据
|
||||||
|
const selectDb = (row: any) => {
|
||||||
|
state.filterDb.param = ''
|
||||||
|
state.filterDb.cache = row;
|
||||||
|
state.filterDb.list = row;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 输入字符过滤schema
|
||||||
|
const filterSchema = () => {
|
||||||
|
if(state.filterDb.param){
|
||||||
|
state.filterDb.list = state.filterDb.cache.filter((a)=>{return String(a).toLowerCase().indexOf(state.filterDb.param) > -1 })
|
||||||
|
}else{
|
||||||
|
state.filterDb.list = state.filterDb.cache;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
...toRefs(state),
|
...toRefs(state),
|
||||||
@@ -639,6 +684,9 @@ export default defineComponent({
|
|||||||
showCreateDdl,
|
showCreateDdl,
|
||||||
dropTable,
|
dropTable,
|
||||||
formatByteSize,
|
formatByteSize,
|
||||||
|
openSqlExec,
|
||||||
|
selectDb,
|
||||||
|
filterSchema,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
<div class="toolbar">
|
<div class="toolbar">
|
||||||
<el-row type="flex" justify="space-between">
|
<el-row type="flex" justify="space-between">
|
||||||
<el-col :span="24">
|
<el-col :span="24">
|
||||||
<project-env-select @changeProjectEnv="changeProjectEnv">
|
<project-env-select @changeProjectEnv="changeProjectEnv" :data="{ projectId, envId:params.envId }">
|
||||||
<template #default>
|
<template #default>
|
||||||
<el-form-item label="资源">
|
<el-form-item label="资源">
|
||||||
<el-select v-model="dbId" placeholder="请选择资源实例" @change="changeDbInstance" filterable style="width: 150px">
|
<el-select v-model="dbId" placeholder="请选择资源实例" @change="changeDbInstance" filterable style="width: 150px">
|
||||||
@@ -299,7 +299,7 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { onMounted, toRefs, reactive, defineComponent, ref } from 'vue';
|
import { onMounted, toRefs, reactive, defineComponent, ref, watch } from 'vue';
|
||||||
import { dbApi } from './api';
|
import { dbApi } from './api';
|
||||||
|
|
||||||
import 'codemirror/addon/hint/show-hint.css';
|
import 'codemirror/addon/hint/show-hint.css';
|
||||||
@@ -321,6 +321,7 @@ import config from '@/common/config';
|
|||||||
import { getSession } from '@/common/utils/storage';
|
import { getSession } from '@/common/utils/storage';
|
||||||
import SqlExecBox from './component/SqlExecBox';
|
import SqlExecBox from './component/SqlExecBox';
|
||||||
import { dateStrFormat } from '@/common/utils/date.ts';
|
import { dateStrFormat } from '@/common/utils/date.ts';
|
||||||
|
import { useStore } from '@/store/index.ts';
|
||||||
|
|
||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
name: 'SqlExec',
|
name: 'SqlExec',
|
||||||
@@ -328,12 +329,14 @@ export default defineComponent({
|
|||||||
ProjectEnvSelect,
|
ProjectEnvSelect,
|
||||||
},
|
},
|
||||||
setup() {
|
setup() {
|
||||||
|
const store = useStore();
|
||||||
const codeTextarea: any = ref(null);
|
const codeTextarea: any = ref(null);
|
||||||
const token = getSession('token');
|
const token = getSession('token');
|
||||||
let codemirror = null as any;
|
let codemirror = null as any;
|
||||||
const tableMap = new Map();
|
const tableMap = new Map();
|
||||||
|
|
||||||
const state = reactive({
|
const state = reactive({
|
||||||
|
projectId: null,
|
||||||
token: token,
|
token: token,
|
||||||
defalutLimit: 20, // 默认查询数量
|
defalutLimit: 20, // 默认查询数量
|
||||||
dbs: [], // 数据库实例列表
|
dbs: [], // 数据库实例列表
|
||||||
@@ -1218,7 +1221,39 @@ export default defineComponent({
|
|||||||
const res = await dbApi.dbs.request(state.params);
|
const res = await dbApi.dbs.request(state.params);
|
||||||
state.dbs = res.list;
|
state.dbs = res.list;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// 加载选中的db
|
||||||
|
const setSelects = async (sqlExecInfo: any) =>{
|
||||||
|
// 保存sql
|
||||||
|
let sql = codemirror?.getValue()
|
||||||
|
if( sql && sql.length > 0 && state.dbId){
|
||||||
|
await saveSql();
|
||||||
|
}
|
||||||
|
// 设置项目id和环境id
|
||||||
|
const { projectId, envId, dbId, db} = sqlExecInfo.dbOptInfo;
|
||||||
|
state.projectId = projectId;
|
||||||
|
state.params.envId = envId
|
||||||
|
// 查询有哪些数据库实例
|
||||||
|
await search()
|
||||||
|
// 加载数据库所有schema
|
||||||
|
changeDbInstance(dbId);
|
||||||
|
state.dbId = dbId
|
||||||
|
state.db = db
|
||||||
|
// 加载schema下所有表
|
||||||
|
changeDb(db)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 判断如果有数据则加载下拉选项
|
||||||
|
let sqlExecInfo = store.state.sqlExecInfo
|
||||||
|
if(sqlExecInfo.dbOptInfo.envId){
|
||||||
|
setSelects(sqlExecInfo)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 监听选中操作的db变化,并加载下拉选项
|
||||||
|
watch(store.state.sqlExecInfo,async (newValue) => {
|
||||||
|
await setSelects(newValue)
|
||||||
|
})
|
||||||
|
|
||||||
return {
|
return {
|
||||||
...toRefs(state),
|
...toRefs(state),
|
||||||
codeTextarea,
|
codeTextarea,
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
<div class="toolbar">
|
<div class="toolbar">
|
||||||
<el-row type="flex" justify="space-between">
|
<el-row type="flex" justify="space-between">
|
||||||
<el-col :span="24">
|
<el-col :span="24">
|
||||||
<project-env-select @changeProjectEnv="changeProjectEnv">
|
<project-env-select @changeProjectEnv="changeProjectEnv" :data="{ projectId, envId:query.envId }">
|
||||||
<template #default>
|
<template #default>
|
||||||
<el-form-item label="实例" label-width="40px">
|
<el-form-item label="实例" label-width="40px">
|
||||||
<el-select v-model="mongoId" placeholder="请选择mongo" @change="changeMongo">
|
<el-select v-model="mongoId" placeholder="请选择mongo" @change="changeMongo">
|
||||||
@@ -130,13 +130,14 @@
|
|||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { mongoApi } from './api';
|
import { mongoApi } from './api';
|
||||||
import { toRefs, ref, reactive, defineComponent } from 'vue';
|
import {toRefs, ref, reactive, defineComponent, watch} from 'vue';
|
||||||
import { ElMessage } from 'element-plus';
|
import { ElMessage } from 'element-plus';
|
||||||
import ProjectEnvSelect from '../component/ProjectEnvSelect.vue';
|
import ProjectEnvSelect from '../component/ProjectEnvSelect.vue';
|
||||||
|
|
||||||
import { isTrue, notBlank, notNull } from '@/common/assert';
|
import { isTrue, notBlank, notNull } from '@/common/assert';
|
||||||
import { formatByteSize } from '@/common/utils/format';
|
import { formatByteSize } from '@/common/utils/format';
|
||||||
import JsonEdit from '@/components/jsonedit/index.vue';
|
import JsonEdit from '@/components/jsonedit/index.vue';
|
||||||
|
import { useStore } from '@/store/index.ts';
|
||||||
|
|
||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
name: 'MongoDataOp',
|
name: 'MongoDataOp',
|
||||||
@@ -145,8 +146,10 @@ export default defineComponent({
|
|||||||
JsonEdit,
|
JsonEdit,
|
||||||
},
|
},
|
||||||
setup() {
|
setup() {
|
||||||
|
const store = useStore();
|
||||||
const findParamInputRef: any = ref(null);
|
const findParamInputRef: any = ref(null);
|
||||||
const state = reactive({
|
const state = reactive({
|
||||||
|
projectId: null,
|
||||||
loading: false,
|
loading: false,
|
||||||
mongoList: [],
|
mongoList: [],
|
||||||
query: {
|
query: {
|
||||||
@@ -416,6 +419,34 @@ export default defineComponent({
|
|||||||
delete state.dataTabs[targetName];
|
delete state.dataTabs[targetName];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// 加载选中的db
|
||||||
|
const setSelects = async (mongoDbOptInfo: any) =>{
|
||||||
|
// 设置项目id和环境id
|
||||||
|
const { projectId, envId, dbId, db} = mongoDbOptInfo.dbOptInfo;
|
||||||
|
state.projectId = projectId;
|
||||||
|
state.query.envId = envId
|
||||||
|
await searchMongo();
|
||||||
|
state.mongoId = dbId
|
||||||
|
await getDatabases();
|
||||||
|
state.database = db
|
||||||
|
await getCollections();
|
||||||
|
if(state.collection){
|
||||||
|
state.collection = ''
|
||||||
|
state.dataTabs = {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 判断如果有数据则加载下拉选项
|
||||||
|
let mongoDbOptInfo = store.state.mongoDbOptInfo
|
||||||
|
if(mongoDbOptInfo.dbOptInfo.envId){
|
||||||
|
setSelects(mongoDbOptInfo)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 监听选中操作的db变化,并加载下拉选项
|
||||||
|
watch(store.state.mongoDbOptInfo,async (newValue) => {
|
||||||
|
await setSelects(newValue)
|
||||||
|
})
|
||||||
|
|
||||||
return {
|
return {
|
||||||
...toRefs(state),
|
...toRefs(state),
|
||||||
findParamInputRef,
|
findParamInputRef,
|
||||||
|
|||||||
@@ -35,7 +35,7 @@
|
|||||||
|
|
||||||
<el-table-column label="操作" width>
|
<el-table-column label="操作" width>
|
||||||
<template #default="scope">
|
<template #default="scope">
|
||||||
<el-link type="primary" @click="showDatabases(scope.row.id)" plain size="small" :underline="false">数据库</el-link>
|
<el-link type="primary" @click="showDatabases(scope.row.id, scope.row)" plain size="small" :underline="false">数据库</el-link>
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
</el-table>
|
</el-table>
|
||||||
@@ -61,11 +61,13 @@
|
|||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column min-width="80" property="Empty" label="是否为空" />
|
<el-table-column min-width="80" property="Empty" label="是否为空" />
|
||||||
|
|
||||||
<el-table-column min-width="80" label="操作">
|
<el-table-column min-width="150" label="操作">
|
||||||
<template #default="scope">
|
<template #default="scope">
|
||||||
<el-link type="success" @click="showDatabaseStats(scope.row.Name)" plain size="small" :underline="false">stats</el-link>
|
<el-link type="success" @click="showDatabaseStats(scope.row.Name)" plain size="small" :underline="false">stats</el-link>
|
||||||
<el-divider direction="vertical" border-style="dashed" />
|
<el-divider direction="vertical" border-style="dashed" />
|
||||||
<el-link type="primary" @click="showCollections(scope.row.Name)" plain size="small" :underline="false">集合</el-link>
|
<el-link type="primary" @click="showCollections(scope.row.Name)" plain size="small" :underline="false">集合</el-link>
|
||||||
|
<el-divider direction="vertical" border-style="dashed" />
|
||||||
|
<el-link type="primary" @click="openDataOps(scope.row)" plain size="small" :underline="false">数据操作</el-link>
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
</el-table>
|
</el-table>
|
||||||
@@ -195,6 +197,8 @@ import { ElMessage, ElMessageBox } from 'element-plus';
|
|||||||
import { projectApi } from '../project/api.ts';
|
import { projectApi } from '../project/api.ts';
|
||||||
import MongoEdit from './MongoEdit.vue';
|
import MongoEdit from './MongoEdit.vue';
|
||||||
import { formatByteSize } from '@/common/utils/format';
|
import { formatByteSize } from '@/common/utils/format';
|
||||||
|
import {store} from '@/store';
|
||||||
|
import router from '@/router';
|
||||||
|
|
||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
name: 'MongoList',
|
name: 'MongoList',
|
||||||
@@ -203,6 +207,12 @@ export default defineComponent({
|
|||||||
},
|
},
|
||||||
setup() {
|
setup() {
|
||||||
const state = reactive({
|
const state = reactive({
|
||||||
|
dbOps: {
|
||||||
|
projectId: null,
|
||||||
|
envId: null,
|
||||||
|
dbId: 0,
|
||||||
|
db: '',
|
||||||
|
},
|
||||||
projects: [],
|
projects: [],
|
||||||
list: [],
|
list: [],
|
||||||
total: 0,
|
total: 0,
|
||||||
@@ -265,7 +275,12 @@ export default defineComponent({
|
|||||||
state.currentData = item;
|
state.currentData = item;
|
||||||
};
|
};
|
||||||
|
|
||||||
const showDatabases = async (id: number) => {
|
const showDatabases = async (id: number, row: any) => {
|
||||||
|
const {projectId, envId} = row;
|
||||||
|
state.dbOps.projectId = projectId
|
||||||
|
state.dbOps.envId = envId
|
||||||
|
state.dbOps.dbId = id
|
||||||
|
|
||||||
state.databaseDialog.data = (await mongoApi.databases.request({ id })).Databases;
|
state.databaseDialog.data = (await mongoApi.databases.request({ id })).Databases;
|
||||||
state.databaseDialog.title = `数据库列表`;
|
state.databaseDialog.title = `数据库列表`;
|
||||||
state.databaseDialog.visible = true;
|
state.databaseDialog.visible = true;
|
||||||
@@ -391,6 +406,24 @@ export default defineComponent({
|
|||||||
state.currentData = null;
|
state.currentData = null;
|
||||||
search();
|
search();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const openDataOps = ( row: any) => {
|
||||||
|
state.dbOps.db = row.Name
|
||||||
|
|
||||||
|
let data = {
|
||||||
|
projectId: state.dbOps.projectId,
|
||||||
|
envId: state.dbOps.envId,
|
||||||
|
dbId: state.dbOps.dbId,
|
||||||
|
db: state.dbOps.db,
|
||||||
|
}
|
||||||
|
console.log(data)
|
||||||
|
// 判断db是否发生改变
|
||||||
|
let oldDb = store.state.mongoDbOptInfo.dbOptInfo.db;
|
||||||
|
if(oldDb !== row.Name){
|
||||||
|
store.dispatch('mongoDbOptInfo/setMongoDbOptInfo', data);
|
||||||
|
}
|
||||||
|
router.push({name: 'MongoDataOp'});
|
||||||
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
...toRefs(state),
|
...toRefs(state),
|
||||||
@@ -409,6 +442,7 @@ export default defineComponent({
|
|||||||
deleteMongo,
|
deleteMongo,
|
||||||
editMongo,
|
editMongo,
|
||||||
valChange,
|
valChange,
|
||||||
|
openDataOps,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -4,11 +4,16 @@
|
|||||||
<div style="float: left">
|
<div style="float: left">
|
||||||
<el-row type="flex" justify="space-between">
|
<el-row type="flex" justify="space-between">
|
||||||
<el-col :span="24">
|
<el-col :span="24">
|
||||||
<project-env-select @changeProjectEnv="changeProjectEnv" @clear="clearRedis">
|
<project-env-select @changeProjectEnv="changeProjectEnv" @clear="clearRedis" :data="{ projectId, envId:query.envId }" >
|
||||||
<template #default>
|
<template #default>
|
||||||
<el-form-item label="redis" label-width="40px">
|
<el-form-item label="redis" label-width="40px">
|
||||||
<el-select v-model="scanParam.id" placeholder="请选择redis" @change="changeRedis" @clear="clearRedis" clearable>
|
<el-select v-model="scanParam.id" placeholder="请选择redis" @change="changeRedis" @clear="clearRedis" clearable>
|
||||||
<el-option v-for="item in redisList" :key="item.id" :label="item.host" :value="item.id"> </el-option>
|
<el-option v-for="item in redisList" :key="item.id" :value="item.id" :label=" item.remark ">
|
||||||
|
<span style="float: left">{{ item.remark }}</span>
|
||||||
|
<span style="float: right; color: #8492a6; margin-left: 6px; font-size: 13px">{{
|
||||||
|
`${item.host}`
|
||||||
|
}}</span>
|
||||||
|
</el-option>
|
||||||
</el-select>
|
</el-select>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label="库" label-width="20px">
|
<el-form-item label="库" label-width="20px">
|
||||||
@@ -125,7 +130,7 @@
|
|||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { redisApi } from './api';
|
import { redisApi } from './api';
|
||||||
import { toRefs, reactive, defineComponent } from 'vue';
|
import {toRefs, reactive, defineComponent, watch} from 'vue';
|
||||||
import { ElMessage, ElMessageBox } from 'element-plus';
|
import { ElMessage, ElMessageBox } from 'element-plus';
|
||||||
import ProjectEnvSelect from '../component/ProjectEnvSelect.vue';
|
import ProjectEnvSelect from '../component/ProjectEnvSelect.vue';
|
||||||
import HashValue from './HashValue.vue';
|
import HashValue from './HashValue.vue';
|
||||||
@@ -133,6 +138,7 @@ import StringValue from './StringValue.vue';
|
|||||||
import SetValue from './SetValue.vue';
|
import SetValue from './SetValue.vue';
|
||||||
import ListValue from './ListValue.vue';
|
import ListValue from './ListValue.vue';
|
||||||
import { isTrue, notBlank, notNull } from '@/common/assert';
|
import { isTrue, notBlank, notNull } from '@/common/assert';
|
||||||
|
import { useStore } from '@/store/index.ts';
|
||||||
|
|
||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
name: 'DataOperation',
|
name: 'DataOperation',
|
||||||
@@ -144,7 +150,9 @@ export default defineComponent({
|
|||||||
ProjectEnvSelect,
|
ProjectEnvSelect,
|
||||||
},
|
},
|
||||||
setup() {
|
setup() {
|
||||||
|
let store = useStore();
|
||||||
const state = reactive({
|
const state = reactive({
|
||||||
|
projectId: null,
|
||||||
loading: false,
|
loading: false,
|
||||||
redisList: [],
|
redisList: [],
|
||||||
dbList: [],
|
dbList: [],
|
||||||
@@ -153,7 +161,7 @@ export default defineComponent({
|
|||||||
},
|
},
|
||||||
scanParam: {
|
scanParam: {
|
||||||
id: null,
|
id: null,
|
||||||
db: null,
|
db: '',
|
||||||
match: null,
|
match: null,
|
||||||
count: 10,
|
count: 10,
|
||||||
cursor: {},
|
cursor: {},
|
||||||
@@ -200,7 +208,7 @@ export default defineComponent({
|
|||||||
|
|
||||||
const changeRedis = (id: number) => {
|
const changeRedis = (id: number) => {
|
||||||
resetScanParam(id);
|
resetScanParam(id);
|
||||||
state.scanParam.db = null;
|
state.scanParam.db = '';
|
||||||
state.dbList = (state.redisList.find((x: any) => x.id == id) as any).db.split(',');
|
state.dbList = (state.redisList.find((x: any) => x.id == id) as any).db.split(',');
|
||||||
state.keys = [];
|
state.keys = [];
|
||||||
state.dbsize = 0;
|
state.dbsize = 0;
|
||||||
@@ -244,7 +252,7 @@ export default defineComponent({
|
|||||||
state.redisList = [];
|
state.redisList = [];
|
||||||
state.scanParam.id = null;
|
state.scanParam.id = null;
|
||||||
resetScanParam();
|
resetScanParam();
|
||||||
state.scanParam.db = null;
|
state.scanParam.db = '';
|
||||||
state.keys = [];
|
state.keys = [];
|
||||||
state.dbsize = 0;
|
state.dbsize = 0;
|
||||||
};
|
};
|
||||||
@@ -383,7 +391,33 @@ export default defineComponent({
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
return {
|
// 加载选中的db
|
||||||
|
const setSelects = async (redisDbOptInfo: any) =>{
|
||||||
|
// 设置项目id和环境id
|
||||||
|
const { projectId, envId, dbId} = redisDbOptInfo.dbOptInfo;
|
||||||
|
state.projectId = projectId;
|
||||||
|
state.query.envId = envId
|
||||||
|
await searchRedis()
|
||||||
|
state.scanParam.id = dbId
|
||||||
|
changeRedis(dbId)
|
||||||
|
if(!state.scanParam.db){
|
||||||
|
state.scanParam.db = '0'
|
||||||
|
}
|
||||||
|
changeDb()
|
||||||
|
}
|
||||||
|
|
||||||
|
// 判断如果有数据则加载下拉选项
|
||||||
|
let redisDbOptInfo = store.state.redisDbOptInfo
|
||||||
|
if(redisDbOptInfo.dbOptInfo.envId){
|
||||||
|
setSelects(redisDbOptInfo)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 监听选中操作的db变化,并加载下拉选项
|
||||||
|
watch(store.state.redisDbOptInfo,async (newValue) => {
|
||||||
|
await setSelects(newValue)
|
||||||
|
})
|
||||||
|
|
||||||
|
return {
|
||||||
...toRefs(state),
|
...toRefs(state),
|
||||||
changeProjectEnv,
|
changeProjectEnv,
|
||||||
changeRedis,
|
changeRedis,
|
||||||
|
|||||||
@@ -82,7 +82,7 @@ export default defineComponent({
|
|||||||
require: true,
|
require: true,
|
||||||
},
|
},
|
||||||
db: {
|
db: {
|
||||||
type: [Number],
|
type: [String],
|
||||||
require: true,
|
require: true,
|
||||||
},
|
},
|
||||||
keyInfo: {
|
keyInfo: {
|
||||||
@@ -98,7 +98,7 @@ export default defineComponent({
|
|||||||
dialogVisible: false,
|
dialogVisible: false,
|
||||||
operationType: 1,
|
operationType: 1,
|
||||||
redisId: 0,
|
redisId: 0,
|
||||||
db: 0,
|
db: '0',
|
||||||
key: {
|
key: {
|
||||||
key: '',
|
key: '',
|
||||||
type: 'hash',
|
type: 'hash',
|
||||||
@@ -107,7 +107,7 @@ export default defineComponent({
|
|||||||
scanParam: {
|
scanParam: {
|
||||||
key: '',
|
key: '',
|
||||||
id: 0,
|
id: 0,
|
||||||
db: 0,
|
db: '0',
|
||||||
cursor: 0,
|
cursor: 0,
|
||||||
match: '',
|
match: '',
|
||||||
count: 10,
|
count: 10,
|
||||||
@@ -261,4 +261,4 @@ export default defineComponent({
|
|||||||
max-width: 70px;
|
max-width: 70px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -75,7 +75,7 @@ export default defineComponent({
|
|||||||
require: true,
|
require: true,
|
||||||
},
|
},
|
||||||
db: {
|
db: {
|
||||||
type: [Number],
|
type: [String],
|
||||||
require: true,
|
require: true,
|
||||||
},
|
},
|
||||||
keyInfo: {
|
keyInfo: {
|
||||||
@@ -95,7 +95,7 @@ export default defineComponent({
|
|||||||
dialogVisible: false,
|
dialogVisible: false,
|
||||||
operationType: 1,
|
operationType: 1,
|
||||||
redisId: '',
|
redisId: '',
|
||||||
db: 0,
|
db: '0',
|
||||||
key: {
|
key: {
|
||||||
key: '',
|
key: '',
|
||||||
type: 'string',
|
type: 'string',
|
||||||
@@ -210,4 +210,4 @@ export default defineComponent({
|
|||||||
max-width: 70px;
|
max-width: 70px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -29,18 +29,17 @@
|
|||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column prop="creator" label="创建人" min-width="100"></el-table-column>
|
<el-table-column prop="creator" label="创建人" min-width="100"></el-table-column>
|
||||||
<el-table-column label="更多" min-width="130" fixed="right">
|
<el-table-column label="更多" min-width="155" fixed="right">
|
||||||
<template #default="scope">
|
<template #default="scope">
|
||||||
<el-link
|
<el-link
|
||||||
v-if="scope.row.mode == 'standalone' || scope.row.mode == 'sentinel'"
|
v-if="scope.row.mode == 'standalone' || scope.row.mode == 'sentinel'"
|
||||||
type="primary"
|
type="primary"
|
||||||
@click="info(scope.row)"
|
@click="info(scope.row)"
|
||||||
:underline="false"
|
:underline="false"
|
||||||
>单机信息</el-link
|
>单机信息</el-link>
|
||||||
>
|
<el-link @click="onShowClusterInfo(scope.row)" v-if="scope.row.mode == 'cluster'" type="success" :underline="false">集群信息</el-link>
|
||||||
<el-link @click="onShowClusterInfo(scope.row)" v-if="scope.row.mode == 'cluster'" type="success" :underline="false"
|
<el-divider direction="vertical" border-style="dashed" />
|
||||||
>集群信息</el-link
|
<el-link @click="openDataOpt(scope.row)" type="success" :underline="false">数据操作</el-link>
|
||||||
>
|
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
</el-table>
|
</el-table>
|
||||||
@@ -153,6 +152,8 @@ import { toRefs, reactive, defineComponent, onMounted } from 'vue';
|
|||||||
import { ElMessage, ElMessageBox } from 'element-plus';
|
import { ElMessage, ElMessageBox } from 'element-plus';
|
||||||
import { projectApi } from '../project/api.ts';
|
import { projectApi } from '../project/api.ts';
|
||||||
import RedisEdit from './RedisEdit.vue';
|
import RedisEdit from './RedisEdit.vue';
|
||||||
|
import {store} from '@/store';
|
||||||
|
import router from '@/router';
|
||||||
|
|
||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
name: 'RedisList',
|
name: 'RedisList',
|
||||||
@@ -284,6 +285,22 @@ export default defineComponent({
|
|||||||
state.currentData = null;
|
state.currentData = null;
|
||||||
search();
|
search();
|
||||||
};
|
};
|
||||||
|
// 打开redis数据操作页
|
||||||
|
const openDataOpt = (row : any) => {
|
||||||
|
const {projectId, envId, id, db} = row;
|
||||||
|
// 判断db是否发生改变
|
||||||
|
let oldDbId = store.state.redisDbOptInfo.dbOptInfo.dbId;
|
||||||
|
if(oldDbId !== id){
|
||||||
|
let params = {
|
||||||
|
projectId,
|
||||||
|
envId,
|
||||||
|
dbId: id,
|
||||||
|
db
|
||||||
|
}
|
||||||
|
store.dispatch('redisDbOptInfo/setRedisDbOptInfo', params);
|
||||||
|
}
|
||||||
|
router.push({name: 'DataOperation'});
|
||||||
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
...toRefs(state),
|
...toRefs(state),
|
||||||
@@ -296,6 +313,7 @@ export default defineComponent({
|
|||||||
deleteRedis,
|
deleteRedis,
|
||||||
editRedis,
|
editRedis,
|
||||||
valChange,
|
valChange,
|
||||||
|
openDataOpt,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -54,7 +54,7 @@ export default defineComponent({
|
|||||||
require: true,
|
require: true,
|
||||||
},
|
},
|
||||||
db: {
|
db: {
|
||||||
type: [Number],
|
type: [String],
|
||||||
require: true,
|
require: true,
|
||||||
},
|
},
|
||||||
keyInfo: {
|
keyInfo: {
|
||||||
@@ -74,7 +74,7 @@ export default defineComponent({
|
|||||||
dialogVisible: false,
|
dialogVisible: false,
|
||||||
operationType: 1,
|
operationType: 1,
|
||||||
redisId: '',
|
redisId: '',
|
||||||
db: 0,
|
db: '0',
|
||||||
key: {
|
key: {
|
||||||
key: '',
|
key: '',
|
||||||
type: 'string',
|
type: 'string',
|
||||||
@@ -161,4 +161,4 @@ export default defineComponent({
|
|||||||
max-width: 70px;
|
max-width: 70px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -49,7 +49,7 @@ export default defineComponent({
|
|||||||
require: true,
|
require: true,
|
||||||
},
|
},
|
||||||
db: {
|
db: {
|
||||||
type: [Number],
|
type: [String],
|
||||||
require: true,
|
require: true,
|
||||||
},
|
},
|
||||||
keyInfo: {
|
keyInfo: {
|
||||||
@@ -66,7 +66,7 @@ export default defineComponent({
|
|||||||
dialogVisible: false,
|
dialogVisible: false,
|
||||||
operationType: 1,
|
operationType: 1,
|
||||||
redisId: '',
|
redisId: '',
|
||||||
db: 0,
|
db: '0',
|
||||||
key: {
|
key: {
|
||||||
key: '',
|
key: '',
|
||||||
type: 'string',
|
type: 'string',
|
||||||
@@ -180,4 +180,4 @@ export default defineComponent({
|
|||||||
max-width: 70px;
|
max-width: 70px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
Reference in New Issue
Block a user