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