feat: 新增数据库导出功能&其他小优化

This commit is contained in:
meilin.huang
2022-06-30 16:42:25 +08:00
parent 64b49dae2e
commit fe8cd93c78
11 changed files with 234 additions and 31 deletions

View File

@@ -30,7 +30,7 @@ import { useStore } from '@/store/index.ts';
export default defineComponent({
name: 'layoutBreadcrumbSearch',
setup() {
const layoutMenuAutocompleteRef = ref();
const layoutMenuAutocompleteRef: any = ref(null);
const store = useStore();
const router = useRouter();
const state: any = reactive({
@@ -68,7 +68,6 @@ export default defineComponent({
// 初始化菜单数据
const initTageView = () => {
if (state.tagsViewList.length > 0) return false;
console.log(getRoutes(store.state.routesList.routesList));
getRoutes(store.state.routesList.routesList).map((v: any) => {
if (!v.meta.isHide) {
state.tagsViewList.push({ ...v });

View File

@@ -72,6 +72,32 @@
<el-dialog width="75%" :title="`${db} 表信息`" :before-close="closeTableInfo" v-model="tableInfoDialog.visible">
<el-row class="mb10">
<el-popover v-model:visible="showDumpInfo" :width="470" placement="right">
<template #reference>
<el-button class="ml5" type="success" size="small" @click="showDumpInfo = !showDumpInfo">导出</el-button>
</template>
<el-form-item label="导出内容: ">
<el-radio-group v-model="dumpInfo.type">
<el-radio :label="1" size="small">结构</el-radio>
<el-radio :label="2" size="small">数据</el-radio>
<el-radio :label="3" size="small">结构数据</el-radio>
</el-radio-group>
</el-form-item>
<el-form-item label="导出表: ">
<el-table @selection-change="handleDumpTableSelectionChange" max-height="300" size="small" :data="tableInfoDialog.infos">
<el-table-column type="selection" width="45" />
<el-table-column property="tableName" label="表名" min-width="150" show-overflow-tooltip> </el-table-column>
<el-table-column property="tableComment" label="备注" min-width="150" show-overflow-tooltip></el-table-column>
</el-table>
</el-form-item>
<div style="text-align: right">
<el-button @click="showDumpInfo = false" size="small">取消</el-button>
<el-button @click="dump(db)" type="success" size="small">确定</el-button>
</div>
</el-popover>
<el-button type="primary" size="small" @click="tableCreateDialog.visible = true">创建表</el-button>
</el-row>
<el-table v-loading="tableInfoDialog.loading" border stripe :data="tableInfoDialog.infos" size="small">
@@ -226,6 +252,10 @@ import { dbApi } from './api';
import enums from './enums';
import { projectApi } from '../project/api.ts';
import SqlExecBox from './component/SqlExecBox.ts';
import config from '@/common/config';
import { getSession } from '@/common/utils/storage';
import { isTrue } from '@/common/assert';
export default defineComponent({
name: 'DbList',
components: {
@@ -255,6 +285,13 @@ export default defineComponent({
},
datas: [],
total: 0,
showDumpInfo: false,
dumpInfo: {
id: 0,
db: '',
type: 3,
tables: [],
},
// sql执行记录弹框
sqlExecLogDialog: {
title: '',
@@ -392,6 +429,29 @@ export default defineComponent({
searchSqlExecLog();
};
/**
* 选择导出数据库表
*/
const handleDumpTableSelectionChange = (vals: any) => {
state.dumpInfo.tables = vals.map((x: any) => x.tableName);
};
/**
* 数据库信息导出
*/
const dump = (db: string) => {
isTrue(state.dumpInfo.tables.length > 0, '请选择要导出的表');
const a = document.createElement('a');
a.setAttribute(
'href',
`${config.baseApiUrl}/dbs/${state.dbId}/dump?db=${db}&type=${state.dumpInfo.type}&tables=${state.dumpInfo.tables.join(
','
)}&token=${getSession('token')}`
);
a.click();
state.showDumpInfo = false;
};
const onShowRollbackSql = async (sqlExecLog: any) => {
const columns = await dbApi.columnMetadata.request({ id: sqlExecLog.dbId, db: sqlExecLog.db, tableName: sqlExecLog.table });
const primaryKey = columns[0].columnName;
@@ -447,6 +507,7 @@ export default defineComponent({
};
const closeTableInfo = () => {
state.showDumpInfo = false;
state.tableInfoDialog.visible = false;
state.tableInfoDialog.infos = [];
};
@@ -516,6 +577,8 @@ export default defineComponent({
valChange,
deleteDb,
onShowSqlExec,
handleDumpTableSelectionChange,
dump,
onBeforeCloseSqlExecDialog,
handleSqlExecPageChange,
searchSqlExecLog,

View File

@@ -927,7 +927,7 @@ export default defineComponent({
return;
}
// 转为字符串比较,可能存在数字等
let text = row[property] + '';
let text = (row[property] ? row[property] : '') + '';
let div = cell.children[0];
if (div) {
let input = document.createElement('input');

View File

@@ -5,6 +5,7 @@ export const dbApi = {
dbs: Api.create("/dbs", 'get'),
saveDb: Api.create("/dbs", 'post'),
deleteDb: Api.create("/dbs/{id}", 'delete'),
dumpDb: Api.create("/dbs/{id}/dump", 'post'),
tableInfos: Api.create("/dbs/{id}/t-infos", 'get'),
tableIndex: Api.create("/dbs/{id}/t-index", 'get'),
tableDdl: Api.create("/dbs/{id}/t-create-ddl", 'get'),

View File

@@ -2,7 +2,7 @@
<div>
<el-dialog title="待执行SQL" v-model="dialogVisible" :show-close="false" width="600px">
<codemirror height="350px" class="codesql" ref="cmEditor" language="sql" v-model="sqlValue" :options="cmOptions" />
<el-input v-model="remark" placeholder="请输入执行备注" class="mt5" />
<el-input ref="remarkInputRef" v-model="remark" placeholder="请输入执行备注" class="mt5" />
<template #footer>
<span class="dialog-footer">
<el-button @click="cancel"> </el-button>
@@ -14,9 +14,9 @@
</template>
<script lang="ts">
import { toRefs, reactive, defineComponent } from 'vue';
import { toRefs, ref, nextTick, reactive, defineComponent } from 'vue';
import { dbApi } from '../api';
import { ElDialog, ElButton, ElInput, ElMessage } from 'element-plus';
import { ElDialog, ElButton, ElInput, ElMessage, InputInstance } from 'element-plus';
// import base style
import 'codemirror/lib/codemirror.css';
// 引入主题后还需要在 options 中指定主题才会生效
@@ -50,6 +50,7 @@ export default defineComponent({
},
},
setup(props: any) {
const remarkInputRef = ref<InputInstance>();
const state = reactive({
dialogVisible: false,
sqlValue: '',
@@ -133,10 +134,14 @@ export default defineComponent({
state.dbId = props.dbId;
state.db = props.db;
state.dialogVisible = true;
nextTick(() => {
remarkInputRef.value?.focus();
});
};
return {
...toRefs(state),
remarkInputRef,
open,
runSql,
cancel,