!180 代码优化与在线SQL执行接口

* 代码优化与在线SQL执行接口
This commit is contained in:
tangyibo
2024-05-20 15:16:08 +00:00
committed by inrgihc
parent c8b0b69ce9
commit 9eb8d8bdc3
60 changed files with 13580 additions and 289 deletions

File diff suppressed because it is too large Load Diff

View File

@@ -17,10 +17,12 @@
"qs": "^6.11.2",
"urlencode": "^1.1.0",
"vue": "^2.5.2",
"vue-codemirror": "^4.0.6",
"vue-count-to": "^1.0.13",
"vue-cron": "^1.0.9",
"vue-hot-reload-api": "^2.3.4",
"vue-router": "^3.0.1"
"vue-router": "^3.0.1",
"vue2-ace-editor": "^0.0.15"
},
"devDependencies": {
"autoprefixer": "^7.1.2",

View File

@@ -27,131 +27,141 @@
</el-scrollbar>
</div>
<div class="table-container">
<span>当前表{{currentNode.schemaName}} / {{currentNode.tableName}}</span>
<el-tabs v-model="activeName">
<el-tab-pane label="基本信息"
name="first">
<el-descriptions title="元数据"
size="small"
:column="1"
colon
border>
<el-descriptions-item label="表名称">{{tableMeta.tableName}}</el-descriptions-item>
<el-descriptions-item label="表类型">{{tableMeta.type}}</el-descriptions-item>
<el-descriptions-item label="模式名">{{tableMeta.schemaName}}</el-descriptions-item>
<el-descriptions-item label="表注释">
<el-input type="textarea"
:rows="2"
v-model="tableMeta.remarks"
auto-complete="off"
:readonly=true></el-input>
</el-descriptions-item>
<el-descriptions-item label="建表DDL">
<el-input type="textarea"
:rows="16"
v-model="tableMeta.createSql"
auto-complete="off"
:readonly=true></el-input>
</el-descriptions-item>
</el-descriptions>
</el-tab-pane>
<el-tab-pane label="字段信息"
name="seconde">
<el-table :header-cell-style="{background:'#eef1f6',color:'#606266'}"
:data="tableMeta.columns"
size="small"
border
style="width: 100%">
<template slot="empty">
<span>单击左侧展开"数据源导航树"来查看表的元数据记录</span>
</template>
<el-table-column prop="fieldName"
min-width="20%"
show-overflow-tooltip
label="名称">
</el-table-column>
<el-table-column prop="typeName"
min-width="20%"
label="类型">
</el-table-column>
<el-table-column prop="fieldType"
min-width="7%"
label="jdbcType">
</el-table-column>
<el-table-column prop="displaySize"
min-width="7%"
label="长度">
</el-table-column>
<el-table-column prop="precision"
min-width="5%"
label="度">
</el-table-column>
<el-table-column prop="scale"
min-width="5%"
label="位数">
</el-table-column>
<el-table-column prop="isPrimaryKey"
min-width="5%"
label="主键">
</el-table-column>
<el-table-column prop="isAutoIncrement"
min-width="5%"
label="自增">
</el-table-column>
<el-table-column prop="isNullable"
min-width="5%"
label="可空">
</el-table-column>
<el-table-column prop="remarks"
min-width="20%"
show-overflow-tooltip
label="注释">
</el-table-column>
</el-table>
</el-tab-pane>
<el-tab-pane label="索引信息"
name="third">
<el-table :header-cell-style="{background:'#eef1f6',color:'#606266'}"
:data="tableMeta.indexes"
size="small"
border
style="width: 100%">
<template slot="empty">
<span>单击左侧展开"数据源导航树"来查看表的元数据记录</span>
</template>
<el-table-column prop="indexType"
min-width="20%"
label="索引类型">
</el-table-column>
<el-table-column prop="indexName"
min-width="20%"
label="索引名称">
</el-table-column>
<el-table-column prop="indexFields"
:formatter="formatIndexFields"
show-overflow-tooltip
min-width="60%"
label="索引字段">
</el-table-column>
</el-table>
</el-tab-pane>
<el-tab-pane class="table-container-data-table"
label="取样数据"
name="fourth">
<el-table :header-cell-style="{background:'#eef1f6',color:'#606266'}"
:data="sampleData.rows"
border>
<template slot="empty">
<span>单击左侧展开"数据源导航树"来查看表的数据记录</span>
</template>
<el-table-column v-for="(item,index) in sampleData.columns"
:prop="item"
:label="item"
:key="index"
show-overflow-tooltip>
</el-table-column>
</el-table>
<el-tabs v-model="tabActiveTabName"
type="border-card">
<el-tab-pane label="元数据"
name="metadata">
<el-tag size="medium">当前表{{currentNode.schemaName}} / {{currentNode.tableName}}</el-tag>
<el-tabs v-model="metadataActiveTabName">
<el-tab-pane label="基本信息"
name="first">
<el-descriptions title="元数据"
size="small"
:column="1"
colon
border>
<el-descriptions-item label="表名称">{{tableMeta.tableName}}</el-descriptions-item>
<el-descriptions-item label="表类型">{{tableMeta.type}}</el-descriptions-item>
<el-descriptions-item label="模式名">{{tableMeta.schemaName}}</el-descriptions-item>
<el-descriptions-item label="表注释">
<el-input type="textarea"
:rows="2"
v-model="tableMeta.remarks"
auto-complete="off"
:readonly=true></el-input>
</el-descriptions-item>
<el-descriptions-item label="建表DDL">
<el-input type="textarea"
:rows="16"
v-model="tableMeta.createSql"
auto-complete="off"
:readonly=true></el-input>
</el-descriptions-item>
</el-descriptions>
</el-tab-pane>
<el-tab-pane label="字段信息"
name="seconde">
<el-table :header-cell-style="{background:'#eef1f6',color:'#606266'}"
:data="tableMeta.columns"
size="small"
border
style="width: 100%">
<template slot="empty">
<span>单击左侧展开"数据源导航树"来查看表的元数据记录</span>
</template>
<el-table-column prop="fieldName"
min-width="20%"
show-overflow-tooltip
label="名称">
</el-table-column>
<el-table-column prop="typeName"
min-width="20%"
label="类型">
</el-table-column>
<el-table-column prop="fieldType"
min-width="7%"
label="jdbcType">
</el-table-column>
<el-table-column prop="displaySize"
min-width="7%"
label="度">
</el-table-column>
<el-table-column prop="precision"
min-width="5%"
label="精度">
</el-table-column>
<el-table-column prop="scale"
min-width="5%"
label="位数">
</el-table-column>
<el-table-column prop="isPrimaryKey"
min-width="5%"
label="主键">
</el-table-column>
<el-table-column prop="isAutoIncrement"
min-width="5%"
label="自增">
</el-table-column>
<el-table-column prop="isNullable"
min-width="5%"
label="可空">
</el-table-column>
<el-table-column prop="remarks"
min-width="20%"
show-overflow-tooltip
label="注释">
</el-table-column>
</el-table>
</el-tab-pane>
<el-tab-pane label="索引信息"
name="third">
<el-table :header-cell-style="{background:'#eef1f6',color:'#606266'}"
:data="tableMeta.indexes"
size="small"
border
style="width: 100%">
<template slot="empty">
<span>单击左侧展开"数据源导航树"来查看表的元数据记录</span>
</template>
<el-table-column prop="indexType"
min-width="20%"
label="索引类型">
</el-table-column>
<el-table-column prop="indexName"
min-width="20%"
label="索引名称">
</el-table-column>
<el-table-column prop="indexFields"
:formatter="formatIndexFields"
show-overflow-tooltip
min-width="60%"
label="索引字段">
</el-table-column>
</el-table>
</el-tab-pane>
<el-tab-pane class="table-container-data-table"
label="取样数据"
name="fourth">
<el-table :header-cell-style="{background:'#eef1f6',color:'#606266'}"
:data="sampleData.rows"
border>
<template slot="empty">
<span>单击左侧展开"数据源导航树"来查看表的数据记录</span>
</template>
<el-table-column v-for="(item,index) in sampleData.columns"
:prop="item"
:label="item"
:key="index"
show-overflow-tooltip>
</el-table-column>
</el-table>
</el-tab-pane>
</el-tabs>
</el-tab-pane>
<!-- <el-tab-pane label="SQL在线"
name="sqlQuery">
<multi-sql-editor ref="sqlEditors"></multi-sql-editor>
</el-tab-pane> -->
</el-tabs>
</div>
</div>
@@ -161,10 +171,13 @@
<script>
import urlencode from "urlencode";
import multiSqlEditor from '@/views/metadata/sqlEditor'
// 参考文章https://blog.csdn.net/m0_50255772/article/details/109484828
export default {
components: {},
components: {
multiSqlEditor
},
data () {
return {
props: {
@@ -180,7 +193,8 @@ export default {
tableName: '-',
schemaName: '-'
},
activeName: 'first',
tabActiveTabName: 'metadata',
metadataActiveTabName: 'first',
tableMeta: {
tableName: '-',
schemaName: '-',
@@ -369,7 +383,8 @@ export default {
var schema = data.value;
var table = data.label;
if (!data.hasChild && datasourceId && schema && table) {
this.activeName = 'first';
this.tabActiveTabName = 'metadata';
this.metadataActiveTabName = 'first';
this.getTableMeta(datasourceId, schema, table);
this.getTableData(datasourceId, schema, table);
}
@@ -477,21 +492,49 @@ export default {
min-width: 350px;
position: relative;
cursor: default;
color: black;
}
.el-tree-node__content {
font-size: small;
height: 16px;
background-color: blanchedalmond;
}
.custom-tree-node {
font-size: 16px;
background-size: 16px;
}
.scroller {
min-width: 200px;
max-height: calc(90vh);
}
.el-select {
display: inline;
}
.tree-container .tree {
overflow: auto;
}
.table-container {
width: 80%;
padding: 10px;
width: 100%;
}
.table-container-data-table {
height: 90%;
overflow-y: auto;
overflow-x: hidden;
}
el-tabs--border-card > .el-tabs__header .el-tabs__item {
margin-left: 8px;
border: none;
border-radius: 8px 8px 0 0;
background-color: #f3f7fe;
padding: 4px 20px;
color: #0065d5;
line-height: 22px;
height: 30px;
}
.el-tabs--border-card > .el-tabs__header .el-tabs__item.is-active {
background-color: #0065d5;
color: #ffffff;
}
</style>

View File

@@ -0,0 +1,121 @@
<template>
<div>
<div class="tool">
<div class="item-button"><i class="iconfont icon-play"></i><span>执行</span></div>
<div class="item-button"><i class="iconfont icon-play"></i><span>执行选中</span></div>
<div class="item-button"><i class="iconfont icon-play"></i><span>格式化</span></div>
</div>
<ace ref="editor"
:value="content"
@init="initEditor"
:lang="lang"
:height="height === 0 ? '100%' : height"
:theme="theme"
:options="options"
width="100%"
v-bind="config">
</ace>
</div>
</template>
<script>
import ace from 'vue2-ace-editor'
export default {
name: "multiSqlEditer",
components: {
ace
},
data () {
return {
}
},
props: {
content: {
type: String,
default: ''
},
height: {
type: Number,
default: 300
},
readOnly: {
type: Boolean,
default: false
},
theme: {
type: String,
default: 'monokai'
},
lang: {
type: String,
default: 'sql'
},
config: {
type: Object,
default: () => {
return {
font_size: 16,
sql_atom: true
}
}
}
},
computed: {
options () {
if (this.readOnly) {
return {
enableBasicAutocompletion: true,
enableSnippets: true,
enableLiveAutocompletion: this.config.sql_atom,
showPrintMargin: false,
fontSize: this.config.font_size,
readOnly: true
}
}
return {
enableBasicAutocompletion: true,
enableSnippets: true,
enableLiveAutocompletion: this.config.sql_atom,
showPrintMargin: false,
fontSize: this.config.font_size
}
}
},
methods: {
initEditor (editor) {
require('brace/ext/language_tools')
// 设置语言
require('brace/mode/sql')
require('brace/snippets/sql')
// 设置主题 按需加载
require('brace/theme/monokai')
require('brace/theme/chrome')
require('brace/theme/crimson_editor')
// 监听值的变化
editor.getSession().on('change', val => {
this.$emit('change', editor.getValue())
})
},
},
mounted () {
},
created () {
},
}
</script>
<style scoped>
.tool .item-button {
display: inline-block;
font-size: 20px;
color: #009966;
margin: 0 20px 0 0;
line-height: 26px;
cursor: pointer;
}
.tool .item-button span {
color: #000;
font-size: 16px;
}
</style>

View File

@@ -33,6 +33,7 @@
</el-card>
<div class="contentBox">
<el-tag v-if="taskId && taskId>0">当前任务[{{taskId}}]{{taskName}}</el-tag>
<div class="right-refresh-button">
<el-button type="primary"
plain
@@ -165,6 +166,7 @@ export default {
pageTaskAssignments: [],
pageTaskAssignmentsTotalCount: 0,
taskId: 0,
taskName: "",
jobTableData: [],
jobScheduleTime: '',
isActive: -1,
@@ -225,25 +227,43 @@ export default {
this.currentPage = currentPage;
this.loadJobsData();
},
loadJobsData: function () {
this.$http.get(
"/dbswitch/admin/api/v1/ops/jobs/list/" + this.currentPage + "/" + this.pageSize + "?id=" + this.taskId
).then(res => {
if (0 === res.data.code) {
this.currentPage = res.data.pagination.page;
this.pageSize = res.data.pagination.size;
this.totalCount = res.data.pagination.total;
this.jobTableData = res.data.data;
} else {
if (res.data.message) {
alert("查询JOB执行历史纪录失败," + res.data.message);
loadTaskInfo: function () {
if (this.taskId && this.taskId > 0) {
this.$http.get(
"/dbswitch/admin/api/v1/assignment/info/id/" + this.taskId
).then(res => {
if (0 === res.data.code) {
this.taskName = res.data.data.name;
} else {
if (res.data.message) {
alert("查询任务详情失败," + res.data.message);
}
}
}
});
});
}
},
loadJobsData: function () {
if (this.taskId && this.taskId > 0) {
this.$http.get(
"/dbswitch/admin/api/v1/ops/jobs/list/" + this.currentPage + "/" + this.pageSize + "?id=" + this.taskId
).then(res => {
if (0 === res.data.code) {
this.currentPage = res.data.pagination.page;
this.pageSize = res.data.pagination.size;
this.totalCount = res.data.pagination.total;
this.jobTableData = res.data.data;
} else {
if (res.data.message) {
alert("查询JOB执行历史纪录失败," + res.data.message);
}
}
});
}
},
handleChooseClick: function (taskId, index) {
this.isActive = index;
this.taskId = taskId;
this.loadTaskInfo();
this.loadJobsData();
},
handleClickRefresh () {
@@ -251,6 +271,7 @@ export default {
alert("请先在左侧选择一个任务来");
return;
}
this.loadTaskInfo();
this.loadJobsData();
},
handleCancelJob: function (jobId) {
@@ -333,6 +354,7 @@ export default {
this.loadPageTaskAssignments();
if (this.$route.query.id) {
this.taskId = this.$route.query.id
this.loadTaskInfo();
this.loadJobsData();
}
},