mirror of
https://gitee.com/dromara/mayfly-go
synced 2025-11-02 07:20:24 +08:00
review: 数据库实例管理调整
This commit is contained in:
@@ -25,7 +25,7 @@ export async function RsaEncrypt(value: any) {
|
||||
if (!value) {
|
||||
return '';
|
||||
}
|
||||
if (encryptor != null) {
|
||||
if (encryptor != null && sessionStorage.getItem('RsaPublicKey') != null) {
|
||||
return encryptor.encrypt(value);
|
||||
}
|
||||
encryptor = new JSEncrypt();
|
||||
|
||||
@@ -1,14 +1,39 @@
|
||||
<template>
|
||||
<div>
|
||||
<el-dialog :title="title" v-model="dialogVisible" @open="open" :before-close="cancel" :close-on-click-modal="false" :destroy-on-close="true" width="38%">
|
||||
<el-dialog
|
||||
:title="title"
|
||||
v-model="dialogVisible"
|
||||
@open="open"
|
||||
:before-close="cancel"
|
||||
:close-on-click-modal="false"
|
||||
:destroy-on-close="true"
|
||||
width="38%"
|
||||
>
|
||||
<el-form :model="form" ref="dbForm" :rules="rules" label-width="auto">
|
||||
<el-form-item prop="tagId" label="标签:" required>
|
||||
<tag-select v-model="form.tagId" v-model:tag-path="form.tagPath" style="width: 100%" />
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item prop="instanceId" label="数据库实例:" required>
|
||||
<el-select :disabled="form.id !== undefined" @change="getAllDatabase" v-model="form.instanceId" placeholder="请选择实例" filterable clearable style="width: 200px">
|
||||
<el-option v-for="item in state.instances" :key="item.id" :label="item.name" :value="item.id"> </el-option>
|
||||
<el-select
|
||||
:disabled="form.id !== undefined"
|
||||
remote
|
||||
:remote-method="getInstances"
|
||||
@change="getAllDatabase"
|
||||
v-model="form.instanceId"
|
||||
placeholder="请输入实例名称搜索并选择实例"
|
||||
filterable
|
||||
clearable
|
||||
class="w100"
|
||||
>
|
||||
<el-option v-for="item in state.instances" :key="item.id" :label="`${item.name}`" :value="item.id">
|
||||
{{ item.name }}
|
||||
<el-divider direction="vertical" border-style="dashed" />
|
||||
|
||||
{{ item.type }} / {{ item.host }}:{{ item.port }}
|
||||
<el-divider direction="vertical" border-style="dashed" />
|
||||
{{ item.username }}
|
||||
</el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
|
||||
@@ -17,20 +42,20 @@
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item prop="database" label="数据库名:" required>
|
||||
<el-select
|
||||
@change="changeDatabase"
|
||||
v-model="databaseList"
|
||||
multiple
|
||||
clearable
|
||||
collapse-tags
|
||||
collapse-tags-tooltip
|
||||
filterable
|
||||
allow-create
|
||||
placeholder="请确保数据库实例信息填写完整后获取库名"
|
||||
style="width: 100%"
|
||||
>
|
||||
<el-option v-for="db in allDatabases" :key="db" :label="db" :value="db" />
|
||||
</el-select>
|
||||
<el-select
|
||||
@change="changeDatabase"
|
||||
v-model="databaseList"
|
||||
multiple
|
||||
clearable
|
||||
collapse-tags
|
||||
collapse-tags-tooltip
|
||||
filterable
|
||||
allow-create
|
||||
placeholder="请确保数据库实例信息填写完整后获取库名"
|
||||
style="width: 100%"
|
||||
>
|
||||
<el-option v-for="db in allDatabases" :key="db" :label="db" :value="db" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item prop="remark" label="备注:">
|
||||
@@ -146,21 +171,28 @@ const changeDatabase = () => {
|
||||
};
|
||||
|
||||
const getAllDatabase = async () => {
|
||||
const reqForm = { ...state.form };
|
||||
if (state.form.instanceId > 0) {
|
||||
state.allDatabases = await dbApi.getAllDatabase.request(reqForm);
|
||||
state.allDatabases = await dbApi.getAllDatabase.request({ instanceId: state.form.instanceId });
|
||||
}
|
||||
};
|
||||
|
||||
const getAllInstances = async () => {
|
||||
const data = await dbApi.instances.request(null);
|
||||
const getInstances = async (instanceName: string = '', id = 0) => {
|
||||
if (!id && !instanceName) {
|
||||
state.instances = [];
|
||||
return;
|
||||
}
|
||||
const data = await dbApi.instances.request({ id, name: instanceName });
|
||||
if (data) {
|
||||
state.instances = data.list;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const open = async () => {
|
||||
await getAllInstances()
|
||||
await getAllDatabase()
|
||||
if (state.form.instanceId) {
|
||||
// 根据id获取,因为需要回显实例名称
|
||||
getInstances('', state.form.instanceId);
|
||||
}
|
||||
await getAllDatabase();
|
||||
};
|
||||
|
||||
const btnOk = async () => {
|
||||
|
||||
@@ -20,8 +20,23 @@
|
||||
</template>
|
||||
|
||||
<template #instanceSelect>
|
||||
<el-select @focus="getInstances" v-model="query.instanceId" placeholder="请选择实例" filterable clearable style="width: 200px">
|
||||
<el-option v-for="item in instances" :key="item.id" :label="item.name" :value="item.id"> </el-option>
|
||||
<el-select
|
||||
remote
|
||||
:remote-method="getInstances"
|
||||
v-model="query.instanceId"
|
||||
placeholder="输入并选择实例"
|
||||
filterable
|
||||
clearable
|
||||
style="width: 200px"
|
||||
>
|
||||
<el-option v-for="item in state.instances" :key="item.id" :label="`${item.name}`" :value="item.id">
|
||||
{{ item.name }}
|
||||
<el-divider direction="vertical" border-style="dashed" />
|
||||
|
||||
{{ item.type }} / {{ item.host }}:{{ item.port }}
|
||||
<el-divider direction="vertical" border-style="dashed" />
|
||||
{{ item.username }}
|
||||
</el-option>
|
||||
</el-select>
|
||||
</template>
|
||||
|
||||
@@ -234,21 +249,21 @@
|
||||
|
||||
<el-dialog v-model="infoDialog.visible" :before-close="onBeforeCloseInfoDialog" :close-on-click-modal="false">
|
||||
<el-descriptions title="详情" :column="3" border>
|
||||
<el-descriptions-item :span="3" label="标签路径">{{ infoDialog.data.tagPath }}</el-descriptions-item>
|
||||
<el-descriptions-item :span="2" label="名称">{{ infoDialog.data.name }}</el-descriptions-item>
|
||||
<el-descriptions-item :span="1" label="id">{{ infoDialog.data.id }}</el-descriptions-item>
|
||||
<el-descriptions-item :span="3" label="数据库">{{ infoDialog.data.database }}</el-descriptions-item>
|
||||
<el-descriptions-item :span="3" label="备注">{{ infoDialog.data.remark }}</el-descriptions-item>
|
||||
<el-descriptions-item :span="2" label="创建时间">{{ dateFormat(infoDialog.data.createTime) }} </el-descriptions-item>
|
||||
<el-descriptions-item :span="1" label="创建者">{{ infoDialog.data.creator }}</el-descriptions-item>
|
||||
<el-descriptions-item :span="2" label="更新时间">{{ dateFormat(infoDialog.data.updateTime) }} </el-descriptions-item>
|
||||
<el-descriptions-item :span="1" label="修改者">{{ infoDialog.data.modifier }}</el-descriptions-item>
|
||||
<el-descriptions-item :span="3" label="标签路径">{{ infoDialog.data?.tagPath }}</el-descriptions-item>
|
||||
<el-descriptions-item :span="2" label="名称">{{ infoDialog.data?.name }}</el-descriptions-item>
|
||||
<el-descriptions-item :span="1" label="id">{{ infoDialog.data?.id }}</el-descriptions-item>
|
||||
<el-descriptions-item :span="3" label="数据库">{{ infoDialog.data?.database }}</el-descriptions-item>
|
||||
<el-descriptions-item :span="3" label="备注">{{ infoDialog.data?.remark }}</el-descriptions-item>
|
||||
<el-descriptions-item :span="2" label="创建时间">{{ dateFormat(infoDialog.data?.createTime) }} </el-descriptions-item>
|
||||
<el-descriptions-item :span="1" label="创建者">{{ infoDialog.data?.creator }}</el-descriptions-item>
|
||||
<el-descriptions-item :span="2" label="更新时间">{{ dateFormat(infoDialog.data?.updateTime) }} </el-descriptions-item>
|
||||
<el-descriptions-item :span="1" label="修改者">{{ infoDialog.data?.modifier }}</el-descriptions-item>
|
||||
|
||||
<el-descriptions-item :span="3" label="数据库实例名称">{{ infoDialog.instance.name }}</el-descriptions-item>
|
||||
<el-descriptions-item :span="2" label="主机">{{ infoDialog.instance.host }}</el-descriptions-item>
|
||||
<el-descriptions-item :span="1" label="端口">{{ infoDialog.instance.port }}</el-descriptions-item>
|
||||
<el-descriptions-item :span="2" label="用户名">{{ infoDialog.instance.username }}</el-descriptions-item>
|
||||
<el-descriptions-item :span="1" label="类型">{{ infoDialog.instance.type }}</el-descriptions-item>
|
||||
<el-descriptions-item :span="3" label="数据库实例名称">{{ infoDialog.instance?.name }}</el-descriptions-item>
|
||||
<el-descriptions-item :span="2" label="主机">{{ infoDialog.instance?.host }}</el-descriptions-item>
|
||||
<el-descriptions-item :span="1" label="端口">{{ infoDialog.instance?.port }}</el-descriptions-item>
|
||||
<el-descriptions-item :span="2" label="用户名">{{ infoDialog.instance?.username }}</el-descriptions-item>
|
||||
<el-descriptions-item :span="1" label="类型">{{ infoDialog.instance?.type }}</el-descriptions-item>
|
||||
</el-descriptions>
|
||||
</el-dialog>
|
||||
|
||||
@@ -291,10 +306,7 @@ const perms = {
|
||||
delDb: 'db:del',
|
||||
};
|
||||
|
||||
const queryConfig = [
|
||||
TableQuery.slot('tagPath', '标签', 'tagPathSelect'),
|
||||
TableQuery.slot('instanceId', '实例', 'instanceSelect'),
|
||||
];
|
||||
const queryConfig = [TableQuery.slot('tagPath', '标签', 'tagPathSelect'), TableQuery.slot('instanceId', '实例', 'instanceSelect')];
|
||||
|
||||
const columns = ref([
|
||||
TableColumn.new('tagPath', '标签路径').isSlot().setAddWidth(20),
|
||||
@@ -315,7 +327,7 @@ const state = reactive({
|
||||
dbId: 0,
|
||||
db: '',
|
||||
tags: [],
|
||||
instances: [],
|
||||
instances: [] as any,
|
||||
/**
|
||||
* 选中的数据
|
||||
*/
|
||||
@@ -337,7 +349,7 @@ const state = reactive({
|
||||
instance: null as any,
|
||||
query: {
|
||||
instanceId: 0,
|
||||
}
|
||||
},
|
||||
},
|
||||
showDumpInfo: false,
|
||||
dumpInfo: {
|
||||
@@ -504,19 +516,23 @@ const showInfo = async (info: any) => {
|
||||
};
|
||||
|
||||
const onBeforeCloseInfoDialog = () => {
|
||||
state.infoDialog.visible = false;
|
||||
state.infoDialog.data = null;
|
||||
state.infoDialog.instance = null;
|
||||
state.infoDialog.visible = false;
|
||||
state.infoDialog.data = null;
|
||||
state.infoDialog.instance = null;
|
||||
};
|
||||
|
||||
const getTags = async () => {
|
||||
state.tags = await dbApi.dbTags.request(null);
|
||||
};
|
||||
|
||||
const getInstances = async () => {
|
||||
const data = await dbApi.instances.request(null);
|
||||
const getInstances = async (instanceName = '') => {
|
||||
if (!instanceName) {
|
||||
state.instances = [];
|
||||
return;
|
||||
}
|
||||
const data = await dbApi.instances.request({ name: instanceName });
|
||||
if (data) {
|
||||
state.instances = data.list;
|
||||
state.instances = data.list;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -26,13 +26,17 @@
|
||||
<el-input v-model.trim="form.username" placeholder="请输入用户名"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item prop="password" label="密码:">
|
||||
<el-input
|
||||
type="password"
|
||||
show-password
|
||||
v-model.trim="form.password"
|
||||
placeholder="请输入密码"
|
||||
autocomplete="new-password"
|
||||
/>
|
||||
<el-input type="password" show-password v-model.trim="form.password" placeholder="请输入密码" autocomplete="new-password">
|
||||
<template v-if="form.id && form.id != 0" #suffix>
|
||||
<el-popover @hide="pwd = ''" placement="right" title="原密码" :width="200" trigger="click" :content="pwd">
|
||||
<template #reference>
|
||||
<el-link v-auth="'db:instance:save'" @click="getDbPwd" :underline="false" type="primary" class="mr5"
|
||||
>原密码
|
||||
</el-link>
|
||||
</template>
|
||||
</el-popover>
|
||||
</template>
|
||||
</el-input>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item prop="remark" label="备注:">
|
||||
@@ -79,7 +83,6 @@ import { dbApi } from './api';
|
||||
import { ElMessage } from 'element-plus';
|
||||
import { notBlank } from '@/common/assert';
|
||||
import { RsaEncrypt } from '@/common/rsa';
|
||||
import TagSelect from '../component/TagSelect.vue';
|
||||
import SshTunnelSelect from '../component/SshTunnelSelect.vue';
|
||||
|
||||
const props = defineProps({
|
||||
@@ -161,11 +164,11 @@ watch(props, (newValue: any) => {
|
||||
}
|
||||
state.tabActiveName = 'basic';
|
||||
if (newValue.data) {
|
||||
state.form = { ...newValue.data};
|
||||
state.oldUserName = state.form.username
|
||||
state.form = { ...newValue.data };
|
||||
state.oldUserName = state.form.username;
|
||||
} else {
|
||||
state.form = { port: 3306 } as any;
|
||||
state.oldUserName = null
|
||||
state.oldUserName = null;
|
||||
}
|
||||
});
|
||||
|
||||
@@ -177,7 +180,7 @@ const btnOk = async () => {
|
||||
if (!state.form.id) {
|
||||
notBlank(state.form.password, '新增操作,密码不可为空');
|
||||
} else if (state.form.username != state.oldUserName) {
|
||||
notBlank(state.form.password, '已修改用户名,请输入密码');
|
||||
notBlank(state.form.password, '已修改用户名,请输入密码');
|
||||
}
|
||||
|
||||
dbForm.value.validate(async (valid: boolean) => {
|
||||
|
||||
@@ -15,7 +15,9 @@
|
||||
>
|
||||
<template #queryRight>
|
||||
<el-button v-auth="perms.saveInstance" type="primary" icon="plus" @click="editInstance(false)">添加</el-button>
|
||||
<el-button v-auth="perms.delInstance" :disabled="selectionData.length < 1" @click="deleteInstance()" type="danger" icon="delete">删除</el-button>
|
||||
<el-button v-auth="perms.delInstance" :disabled="selectionData.length < 1" @click="deleteInstance()" type="danger" icon="delete"
|
||||
>删除</el-button
|
||||
>
|
||||
</template>
|
||||
|
||||
<template #more="{ data }">
|
||||
@@ -50,12 +52,17 @@
|
||||
</el-descriptions>
|
||||
</el-dialog>
|
||||
|
||||
<instance-edit @val-change="valChange" :title="instanceEditDialog.title" v-model:visible="instanceEditDialog.visible" v-model:data="instanceEditDialog.data"></instance-edit>
|
||||
<instance-edit
|
||||
@val-change="valChange"
|
||||
:title="instanceEditDialog.title"
|
||||
v-model:visible="instanceEditDialog.visible"
|
||||
v-model:data="instanceEditDialog.data"
|
||||
></instance-edit>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { ref, toRefs, reactive, computed, onMounted, defineAsyncComponent } from 'vue';
|
||||
import { ref, toRefs, reactive, onMounted, defineAsyncComponent } from 'vue';
|
||||
import { ElMessage, ElMessageBox } from 'element-plus';
|
||||
import { dbApi } from './api';
|
||||
import { dateFormat } from '@/common/utils/date';
|
||||
@@ -66,8 +73,8 @@ import { hasPerms } from '@/components/auth/auth';
|
||||
const InstanceEdit = defineAsyncComponent(() => import('./InstanceEdit.vue'));
|
||||
|
||||
const perms = {
|
||||
saveInstance: 'instance:save',
|
||||
delInstance: 'instance:del',
|
||||
saveInstance: 'db:instance:save',
|
||||
delInstance: 'db:instance:del',
|
||||
};
|
||||
|
||||
const queryConfig = [TableQuery.text('name', '名称')];
|
||||
@@ -116,16 +123,7 @@ const state = reactive({
|
||||
},
|
||||
});
|
||||
|
||||
const {
|
||||
dbId,
|
||||
db,
|
||||
selectionData,
|
||||
query,
|
||||
datas,
|
||||
total,
|
||||
infoDialog,
|
||||
instanceEditDialog,
|
||||
} = toRefs(state);
|
||||
const { selectionData, query, datas, total, infoDialog, instanceEditDialog } = toRefs(state);
|
||||
|
||||
onMounted(async () => {
|
||||
if (Object.keys(actionBtns).length > 0) {
|
||||
@@ -177,6 +175,5 @@ const deleteInstance = async () => {
|
||||
search();
|
||||
} catch (err) {}
|
||||
};
|
||||
|
||||
</script>
|
||||
<style lang="scss"></style>
|
||||
|
||||
@@ -44,8 +44,7 @@
|
||||
<template #default>
|
||||
<el-form class="instances-pop-form" label-width="55px" :size="'small'">
|
||||
<el-form-item label="类型:">{{ data.params.type }}</el-form-item>
|
||||
<el-form-item label="链接:">{{ data.params.host }}:{{ data.params.port }}</el-form-item>
|
||||
<el-form-item label="用户:">{{ data.params.username }}</el-form-item>
|
||||
<el-form-item label="名称:">{{ data.params.name }}</el-form-item>
|
||||
<el-form-item v-if="data.params.remark" label="备注:">{{ data.params.remark }}</el-form-item>
|
||||
</el-form>
|
||||
</template>
|
||||
@@ -633,12 +632,12 @@ const registerSqlCompletionItemProvider = () => {
|
||||
range,
|
||||
});
|
||||
});
|
||||
|
||||
let replacedFunctions = [] as string[];
|
||||
|
||||
let replacedFunctions = [] as string[];
|
||||
|
||||
// 添加的函数
|
||||
addSqlLanguage.replaceFunctions.forEach((item: any) => {
|
||||
replacedFunctions.push(item.label)
|
||||
replacedFunctions.push(item.label);
|
||||
suggestions.push({
|
||||
label: {
|
||||
label: item.label,
|
||||
@@ -649,18 +648,19 @@ const registerSqlCompletionItemProvider = () => {
|
||||
range,
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
// 内置函数
|
||||
sqlCompletionBuiltinFunctions.forEach((item: any) => {
|
||||
replacedFunctions.indexOf(item) < 0 && suggestions.push({
|
||||
label: {
|
||||
label: item,
|
||||
description: 'func',
|
||||
},
|
||||
kind: monaco.languages.CompletionItemKind.Function,
|
||||
insertText: item,
|
||||
range,
|
||||
});
|
||||
replacedFunctions.indexOf(item) < 0 &&
|
||||
suggestions.push({
|
||||
label: {
|
||||
label: item,
|
||||
description: 'func',
|
||||
},
|
||||
kind: monaco.languages.CompletionItemKind.Function,
|
||||
insertText: item,
|
||||
range,
|
||||
});
|
||||
});
|
||||
// 内置变量
|
||||
sqlCompletionBuiltinVariables.forEach((item: string) => {
|
||||
|
||||
@@ -9,16 +9,16 @@
|
||||
:destroy-on-close="true"
|
||||
width="900px"
|
||||
>
|
||||
<el-form :model="form" ref="scriptForm" label-width="auto">
|
||||
<el-form-item prop="method" label="名称">
|
||||
<el-form :model="form" :rules="rules" ref="scriptForm" label-width="auto">
|
||||
<el-form-item prop="name" label="名称" required>
|
||||
<el-input v-model="form.name" placeholder="请输入名称"></el-input>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item prop="description" label="描述">
|
||||
<el-form-item prop="description" label="描述" required>
|
||||
<el-input v-model="form.description" placeholder="请输入描述"></el-input>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item prop="type" label="类型">
|
||||
<el-form-item prop="type" label="类型" required>
|
||||
<el-select v-model="form.type" default-first-option style="width: 100%" placeholder="请选择类型">
|
||||
<el-option v-for="item in ScriptResultEnum" :key="item.value" :label="item.label" :value="item.value"></el-option>
|
||||
</el-select>
|
||||
@@ -59,7 +59,11 @@
|
||||
</el-row>
|
||||
</el-form-item>
|
||||
|
||||
<monaco-editor v-model="form.script" language="shell" height="300px" />
|
||||
<el-form-item required prop="script" class="100w">
|
||||
<div style="width: 100%">
|
||||
<monaco-editor v-model="form.script" language="shell" height="300px" />
|
||||
</div>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
|
||||
<template #footer>
|
||||
@@ -100,6 +104,37 @@ const props = defineProps({
|
||||
|
||||
const emit = defineEmits(['update:visible', 'cancel', 'submitSuccess']);
|
||||
|
||||
const rules = {
|
||||
name: [
|
||||
{
|
||||
required: true,
|
||||
message: '请输入名称',
|
||||
trigger: ['change', 'blur'],
|
||||
},
|
||||
],
|
||||
description: [
|
||||
{
|
||||
required: true,
|
||||
message: '请输入描述',
|
||||
trigger: ['blur', 'change'],
|
||||
},
|
||||
],
|
||||
type: [
|
||||
{
|
||||
required: true,
|
||||
message: '请选择类型',
|
||||
trigger: ['change', 'blur'],
|
||||
},
|
||||
],
|
||||
script: [
|
||||
{
|
||||
required: true,
|
||||
message: '请输入脚本',
|
||||
trigger: ['blur', 'change'],
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
const { isCommon, machineId } = toRefs(props);
|
||||
const scriptForm: any = ref(null);
|
||||
|
||||
@@ -147,12 +182,8 @@ const onDeleteParam = (idx: number) => {
|
||||
|
||||
const btnOk = () => {
|
||||
state.form.machineId = isCommon.value ? 9999999 : (machineId?.value as any);
|
||||
console.log('machineid:', machineId);
|
||||
scriptForm.value.validate((valid: any) => {
|
||||
if (valid) {
|
||||
notEmpty(state.form.name, '名称不能为空');
|
||||
notEmpty(state.form.description, '描述不能为空');
|
||||
notEmpty(state.form.script, '内容不能为空');
|
||||
if (state.params) {
|
||||
state.form.params = JSON.stringify(state.params);
|
||||
}
|
||||
|
||||
@@ -1,24 +1,23 @@
|
||||
package api
|
||||
|
||||
import (
|
||||
"github.com/gin-gonic/gin"
|
||||
"mayfly-go/internal/db/api/form"
|
||||
"mayfly-go/internal/db/api/vo"
|
||||
"mayfly-go/internal/db/application"
|
||||
"mayfly-go/internal/db/domain/entity"
|
||||
msgapp "mayfly-go/internal/msg/application"
|
||||
"mayfly-go/pkg/biz"
|
||||
"mayfly-go/pkg/ginx"
|
||||
"mayfly-go/pkg/req"
|
||||
"mayfly-go/pkg/utils/cryptox"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
|
||||
type Instance struct {
|
||||
InstanceApp application.Instance
|
||||
DbApp application.Db
|
||||
MsgApp msgapp.Msg
|
||||
}
|
||||
|
||||
// Instances 获取数据库实例信息
|
||||
|
||||
@@ -4,17 +4,9 @@ import "mayfly-go/pkg/model"
|
||||
|
||||
// 数据库实例查询
|
||||
type InstanceQuery struct {
|
||||
model.Model
|
||||
|
||||
Name string `orm:"column(name)" json:"name" form:"name"`
|
||||
Type string `orm:"column(type)" json:"type"` // 类型,mysql oracle等
|
||||
Host string `orm:"column(host)" json:"host"`
|
||||
Port int `orm:"column(port)" json:"port"`
|
||||
Network string `orm:"column(network)" json:"network"`
|
||||
Username string `orm:"column(username)" json:"username"`
|
||||
Password string `orm:"column(password)" json:"-"`
|
||||
Params string `orm:"column(params)" json:"params"`
|
||||
Remark string `orm:"column(remark)" json:"remark"`
|
||||
Id uint64 `json:"id" form:"id"`
|
||||
Name string `json:"name" form:"name"`
|
||||
Host string `json:"host" form:"host"`
|
||||
}
|
||||
|
||||
// 数据库查询实体,不与数据库表字段一一对应
|
||||
|
||||
@@ -17,9 +17,8 @@ func newInstanceRepo() repository.Instance {
|
||||
// 分页获取数据库信息列表
|
||||
func (d *instanceRepoImpl) GetInstanceList(condition *entity.InstanceQuery, pageParam *model.PageParam, toEntity any, orderBy ...string) *model.PageResult[any] {
|
||||
qd := gormx.NewQuery(new(entity.Instance)).
|
||||
Eq("id", condition.Id).
|
||||
Eq("host", condition.Host).
|
||||
Eq("port", condition.Port).
|
||||
Eq("username", condition.Username).
|
||||
Like("name", condition.Name)
|
||||
return gormx.PageQuery(qd, pageParam, toEntity)
|
||||
}
|
||||
|
||||
@@ -3,7 +3,6 @@ package router
|
||||
import (
|
||||
"mayfly-go/internal/db/api"
|
||||
"mayfly-go/internal/db/application"
|
||||
msgapp "mayfly-go/internal/msg/application"
|
||||
"mayfly-go/pkg/req"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
@@ -15,7 +14,6 @@ func InitInstanceRouter(router *gin.RouterGroup) {
|
||||
d := &api.Instance{
|
||||
InstanceApp: application.GetInstanceApp(),
|
||||
DbApp: application.GetDbApp(),
|
||||
MsgApp: msgapp.GetMsgApp(),
|
||||
}
|
||||
|
||||
reqs := [...]*req.Conf{
|
||||
|
||||
@@ -129,12 +129,8 @@ func (m *Machine) GetProcess(rc *req.Ctx) {
|
||||
cmd += fmt.Sprintf("| grep %s ", pname)
|
||||
}
|
||||
|
||||
count := g.Query("count")
|
||||
if count == "" {
|
||||
count = "10"
|
||||
}
|
||||
|
||||
cmd += "| head -n " + count
|
||||
count := ginx.QueryInt(g, "count", 10)
|
||||
cmd += "| head -n " + fmt.Sprintf("%d", count)
|
||||
|
||||
cli := m.MachineApp.GetCli(GetMachineId(rc.GinCtx))
|
||||
biz.ErrIsNilAppendErr(m.TagApp.CanAccess(rc.LoginAccount.Id, cli.GetMachine().TagPath), "%s")
|
||||
|
||||
@@ -104,7 +104,7 @@ func (d *mongoAppImpl) GetMongoInst(id uint64) *MongoInstance {
|
||||
var mongoCliCache = cache.NewTimedCache(consts.MongoConnExpireTime, 5*time.Second).
|
||||
WithUpdateAccessTime(true).
|
||||
OnEvicted(func(key any, value any) {
|
||||
logx.Info("删除mongo连接缓存: id = ", key)
|
||||
logx.Infof("删除mongo连接缓存: id = %s", key)
|
||||
value.(*MongoInstance).Close()
|
||||
})
|
||||
|
||||
|
||||
@@ -635,9 +635,9 @@ INSERT INTO t_sys_resource (id, pid, ui_path, `type`, status, name, code, weight
|
||||
INSERT INTO t_sys_resource (id, pid, ui_path, type, status, name, code, weight, meta, creator_id, creator, modifier_id, modifier, create_time, update_time, is_deleted, delete_time) VALUES(134, 80, 'Mongo452/eggago31/3sblw1Wb/', 2, 1, '删除数据', 'mongo:data:del', 1692674964, 'null', 1, 'admin', 1, 'admin', '2023-08-22 11:29:24', '2023-08-22 11:29:24', 0, NULL);
|
||||
INSERT INTO t_sys_resource (id, pid, ui_path, type, status, name, code, weight, meta, creator_id, creator, modifier_id, modifier, create_time, update_time, is_deleted, delete_time) VALUES(133, 80, 'Mongo452/eggago31/xvpKk36u/', 2, 1, '保存数据', 'mongo:data:save', 1692674943, 'null', 1, 'admin', 1, 'admin', '2023-08-22 11:29:04', '2023-08-22 11:29:11', 0, NULL);
|
||||
INSERT INTO t_sys_resource (id, pid, ui_path, `type`, status, name, code, weight, meta, creator_id, creator, modifier_id, modifier, create_time, update_time, is_deleted, delete_time) VALUES (135, 36, 'dbms23ax/X0f4BxT0/', 1, 1, '数据库实例管理', 'instances', 1693040706, '{\"component\":\"ops/db/InstanceList\",\"icon\":\"Coin\",\"isKeepAlive\":true,\"routeName\":\"InstanceList\"}', 1, 'admin', 1, 'admin', '2023-08-26 09:05:07', '2023-08-29 22:35:11', 0, NULL);
|
||||
INSERT INTO t_sys_resource (id, pid, ui_path, `type`, status, name, code, weight, meta, creator_id, creator, modifier_id, modifier, create_time, update_time, is_deleted, delete_time) VALUES (136, 133, 'dbms23ax/X0f4BxT0/D23fUiBr/', 2, 1, '实例保存', 'instance:save', 1693041001, 'null', 1, 'admin', 1, 'admin', '2023-08-26 09:10:02', '2023-08-26 09:10:02', 0, NULL);
|
||||
INSERT INTO t_sys_resource (id, pid, ui_path, `type`, status, name, code, weight, meta, creator_id, creator, modifier_id, modifier, create_time, update_time, is_deleted, delete_time) VALUES (137, 133, 'dbms23ax/X0f4BxT0/mJlBeTCs/', 2, 1, '基本权限', 'instance', 1693041055, 'null', 1, 'admin', 1, 'admin', '2023-08-26 09:10:55', '2023-08-26 09:10:55', 0, NULL);
|
||||
INSERT INTO t_sys_resource (id, pid, ui_path, `type`, status, name, code, weight, meta, creator_id, creator, modifier_id, modifier, create_time, update_time, is_deleted, delete_time) VALUES (138, 133, 'dbms23ax/X0f4BxT0/Sgg8uPwz/', 2, 1, '实例删除', 'instance:del', 1693041084, 'null', 1, 'admin', 1, 'admin', '2023-08-26 09:11:24', '2023-08-26 09:11:24', 0, NULL);
|
||||
INSERT INTO t_sys_resource (id, pid, ui_path, `type`, status, name, code, weight, meta, creator_id, creator, modifier_id, modifier, create_time, update_time, is_deleted, delete_time) VALUES (136, 135, 'dbms23ax/X0f4BxT0/D23fUiBr/', 2, 1, '实例保存', 'db:instance:save', 1693041001, 'null', 1, 'admin', 1, 'admin', '2023-08-26 09:10:02', '2023-08-26 09:10:02', 0, NULL);
|
||||
INSERT INTO t_sys_resource (id, pid, ui_path, `type`, status, name, code, weight, meta, creator_id, creator, modifier_id, modifier, create_time, update_time, is_deleted, delete_time) VALUES (137, 135, 'dbms23ax/X0f4BxT0/mJlBeTCs/', 2, 1, '基本权限', 'db:instance', 1693041055, 'null', 1, 'admin', 1, 'admin', '2023-08-26 09:10:55', '2023-08-26 09:10:55', 0, NULL);
|
||||
INSERT INTO t_sys_resource (id, pid, ui_path, `type`, status, name, code, weight, meta, creator_id, creator, modifier_id, modifier, create_time, update_time, is_deleted, delete_time) VALUES (138, 135, 'dbms23ax/X0f4BxT0/Sgg8uPwz/', 2, 1, '实例删除', 'db:instance:del', 1693041084, 'null', 1, 'admin', 1, 'admin', '2023-08-26 09:11:24', '2023-08-26 09:11:24', 0, NULL);
|
||||
COMMIT;
|
||||
|
||||
-- ----------------------------
|
||||
|
||||
@@ -28,11 +28,11 @@ BEGIN;
|
||||
|
||||
INSERT INTO t_sys_resource (id, pid, ui_path, `type`, status, name, code, weight, meta, creator_id, creator, modifier_id, modifier, create_time, update_time, is_deleted, delete_time) VALUES (135, 36, 'dbms23ax/X0f4BxT0/', 1, 1, '数据库实例管理', 'instances', 1693040706, '{\"component\":\"ops/db/InstanceList\",\"icon\":\"Coin\",\"isKeepAlive\":true,\"routeName\":\"InstanceList\"}', 1, 'admin', 1, 'admin', '2023-08-26 09:05:07', '2023-08-29 22:35:11', 0, NULL);
|
||||
|
||||
INSERT INTO t_sys_resource (id, pid, ui_path, `type`, status, name, code, weight, meta, creator_id, creator, modifier_id, modifier, create_time, update_time, is_deleted, delete_time) VALUES (136, 133, 'dbms23ax/X0f4BxT0/D23fUiBr/', 2, 1, '实例保存', 'instance:save', 1693041001, 'null', 1, 'admin', 1, 'admin', '2023-08-26 09:10:02', '2023-08-26 09:10:02', 0, NULL);
|
||||
INSERT INTO t_sys_resource (id, pid, ui_path, `type`, status, name, code, weight, meta, creator_id, creator, modifier_id, modifier, create_time, update_time, is_deleted, delete_time) VALUES (136, 135, 'dbms23ax/X0f4BxT0/D23fUiBr/', 2, 1, '实例保存', 'db:instance:save', 1693041001, 'null', 1, 'admin', 1, 'admin', '2023-08-26 09:10:02', '2023-08-26 09:10:02', 0, NULL);
|
||||
|
||||
INSERT INTO t_sys_resource (id, pid, ui_path, `type`, status, name, code, weight, meta, creator_id, creator, modifier_id, modifier, create_time, update_time, is_deleted, delete_time) VALUES (137, 133, 'dbms23ax/X0f4BxT0/mJlBeTCs/', 2, 1, '基本权限', 'instance', 1693041055, 'null', 1, 'admin', 1, 'admin', '2023-08-26 09:10:55', '2023-08-26 09:10:55', 0, NULL);
|
||||
INSERT INTO t_sys_resource (id, pid, ui_path, `type`, status, name, code, weight, meta, creator_id, creator, modifier_id, modifier, create_time, update_time, is_deleted, delete_time) VALUES (137, 135, 'dbms23ax/X0f4BxT0/mJlBeTCs/', 2, 1, '基本权限', 'db:instance', 1693041055, 'null', 1, 'admin', 1, 'admin', '2023-08-26 09:10:55', '2023-08-26 09:10:55', 0, NULL);
|
||||
|
||||
INSERT INTO t_sys_resource (id, pid, ui_path, `type`, status, name, code, weight, meta, creator_id, creator, modifier_id, modifier, create_time, update_time, is_deleted, delete_time) VALUES (138, 133, 'dbms23ax/X0f4BxT0/Sgg8uPwz/', 2, 1, '实例删除', 'instance:del', 1693041084, 'null', 1, 'admin', 1, 'admin', '2023-08-26 09:11:24', '2023-08-26 09:11:24', 0, NULL);
|
||||
INSERT INTO t_sys_resource (id, pid, ui_path, `type`, status, name, code, weight, meta, creator_id, creator, modifier_id, modifier, create_time, update_time, is_deleted, delete_time) VALUES (138, 135, 'dbms23ax/X0f4BxT0/Sgg8uPwz/', 2, 1, '实例删除', 'db:instance:del', 1693041084, 'null', 1, 'admin', 1, 'admin', '2023-08-26 09:11:24', '2023-08-26 09:11:24', 0, NULL);
|
||||
|
||||
INSERT INTO `t_sys_role_resource` (role_id,resource_id,creator_id,creator,create_time,is_deleted,delete_time) VALUES
|
||||
(1,135,1,'admin','2023-08-30 20:17:00', 0, NULL),
|
||||
|
||||
@@ -50,7 +50,6 @@ func (rc *Ctx) Handle(handler HandlerFunc) {
|
||||
}
|
||||
|
||||
handler(rc)
|
||||
rc.timed = time.Since(begin).Milliseconds()
|
||||
if rc.Conf == nil || !rc.Conf.noRes {
|
||||
ginx.SuccessRes(ginCtx, rc.ResData)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user