前端页面优化

This commit is contained in:
inrgihc
2023-09-17 00:10:16 +08:00
parent d31427f22a
commit 14ee86bcd1
38 changed files with 373 additions and 155 deletions

View File

@@ -32,7 +32,7 @@
基于JDBC的分批次读取源端数据库数据并基于insert/copy方式将数据分批写入目的数据库
</p>
<p>
支持有主键表的 增量变更同步 变化数据计算Change Data Calculate功能
支持有主键表的"变化量"同步 变化数据计算Change Data Calculate功能
</p>
</ul>
</div>
@@ -49,7 +49,7 @@
<el-card class="box-card">
<div class="text item">
<p>
dbswitch提供异构关系数据库间的数据迁移同步支持绝大多数关系型数据库包括
dbswitch提供异构关系数据库间的数据迁移同步支持多种数据库包括
</p>
<ul>
<li>甲骨文的Oracle
@@ -75,13 +75,17 @@
<li>国产翰高数据库HighGo
</li>
<li>国产神通数据库Oscar
</li>
</li>
<li>国产南大通用数据库GBase8a
</li>
<li>Apache Hive(只支持为源端)
</li>
<li>Apache Hive(基于JdbcStorageHandler)
</li>
<li>SQLite3
</li>
<li>OpenGuass
</li>
<li>MongoDB
</li>
</ul>
</div>
</el-card>
@@ -113,10 +117,13 @@
dbswitch-product-oscar // -> oscar方言实现类
dbswitch-product-gbase // -> gbase方言实现类
dbswitch-product-mariadb // -> mariadb方言实现类
dbswitch-product-openguass// -> openguass方言实现类
dbswitch-product-db2 // -> db2方言实现类
dbswitch-product-sybase // -> sybase方言实现类
dbswitch-product-hive // -> hive方言实现类
dbswitch-product-sqlite // -> sqlite方言实现类
dbswitch-product-openguass// -> openguass方言实现类
dbswitch-product-mongodb // -> mongodb方言实现类
dbswitch-data // 工具入口模块,读取配置文件中的参数执行异构迁移同步
dbswitch-admin // 在以上模块的基础上引入Quartz的调度服务与接口
dbswitch-admin-ui // 基于Vue2的前段WEB交互页面

View File

@@ -88,6 +88,7 @@ export default {
}).then(res => {
if (0 === res.data.code) {
this.connectionTypes = res.data.data;
this.handleChooseClick('MYSQL',0);
} else {
if (res.data.message) {
alert("初始化数据库类型信息失败:" + res.data.message);

View File

@@ -1,13 +1,24 @@
<template>
<div>
<el-card>
<div align="right"
style="margin:10px 5px;"
width="95%">
<el-button type="primary"
icon="el-icon-document-add"
@click="createFormVisible=true">添加</el-button>
<div class="connection-list-top">
<div class="left-search-input-group">
<div class="left-search-input">
<el-input placeholder="请输入连接名称关键字搜索"
v-model="keyword"
@change="searchByKeyword"
clearable=true
style="width:300px">
</el-input>
</div>
</div>
<div class="right-add-button-group">
<el-button type="primary"
icon="el-icon-document-add"
@click="createFormVisible=true">添加</el-button>
</div>
</div>
<el-table :header-cell-style="{background:'#eef1f6',color:'#606266'}"
:data="tableData"
size="small"
@@ -37,21 +48,42 @@
<el-table-column label="操作"
min-width="30%">
<template slot-scope="scope">
<el-button size="small"
type="success"
@click="handleMore(scope.$index, scope.row)">详情</el-button>
<el-button size="small"
type="warning"
@click="handleTest(scope.$index, scope.row)">测试</el-button>
<el-dropdown size="small"
split-button
type="primary">
更多
<el-dropdown-menu slot="dropdown">
<el-dropdown-item @click.native.prevent="handleUpdate(scope.$index, scope.row)">修改</el-dropdown-item>
<el-dropdown-item @click.native.prevent="handleDelete(scope.$index, scope.row)">删除</el-dropdown-item>
</el-dropdown-menu>
</el-dropdown>
<el-tooltip content="测试"
placement="top"
effect="dark">
<el-button size="small"
type="danger"
icon="el-icon-document-checked"
@click="handleTest(scope.$index, scope.row)"
circle></el-button>
</el-tooltip>
<el-tooltip content="详情"
placement="top"
effect="dark">
<el-button size="small"
type="primary"
icon="el-icon-document"
@click="handleMore(scope.$index, scope.row)"
circle></el-button>
</el-tooltip>
<el-tooltip content="编辑"
placement="top"
effect="dark">
<el-button size="small"
type="warning"
icon="el-icon-edit"
@click="handleUpdate(scope.$index, scope.row)"
circle></el-button>
</el-tooltip>
<el-tooltip content="删除"
placement="top"
effect="dark">
<el-button size="small"
type="success"
icon="el-icon-delete"
@click="handleDelete(scope.$index, scope.row)"
circle></el-button>
</el-tooltip>
</template>
</el-table-column>
</el-table>
@@ -296,6 +328,7 @@ export default {
data () {
return {
loading: true,
keyword: null,
lists: [],
currentPage: 1,
pageSize: 10,
@@ -375,25 +408,34 @@ export default {
methods: {
loadData: function () {
this.$http({
method: "GET",
url: "/dbswitch/admin/api/v1/connection/list/" + this.currentPage + "/" + this.pageSize
}).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.tableData = res.data.data;
} else {
alert("加载任务列表失败:" + res.data.message);
}
method: "POST",
headers: {
'Content-Type': 'application/json'
},
url: "/dbswitch/admin/api/v1/connection/list",
data: JSON.stringify({
searchText: this.keyword,
page: this.currentPage,
size: this.pageSize
})
}).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.tableData = res.data.data;
} else {
alert("加载任务列表失败:" + res.data.message);
}
},
function () {
console.log("failed");
console.log("load connection list failed");
}
);
},
searchByKeyword: function () {
this.loadData();
},
loadDatabaseTypes: function () {
this.databaseType = [];
this.$http({
@@ -598,4 +640,26 @@ export default {
height: 100%;
overflow: auto;
}
.connection-list-top {
width: 100%;
display: flex;
justify-content: space-between;
}
.left-search-input-group {
width: calc(100% - 100px);
margin-right: auto;
display: flex;
justify-content: space-between;
}
.left-search-input {
width: 300px;
margin-right: auto;
margin: 10px 5px;
}
.right-add-button-group {
width: 100px;
margin-left: auto;
margin: 10px 5px;
}
</style>

View File

@@ -1,14 +1,24 @@
<template>
<div>
<el-card>
<div align="right"
style="margin:10px 5px;"
width="65%">
<el-button type="primary"
icon="el-icon-document-add"
size="small"
@click="handleCreate">添加</el-button>
<div class="assignment-list-top">
<div class="left-search-input-group">
<div class="left-search-input">
<el-input placeholder="请输入任务名称关键字搜索"
v-model="keyword"
clearable=true
@change="searchByKeyword"
style="width:300px">
</el-input>
</div>
</div>
<div class="right-add-button-group">
<el-button type="primary"
icon="el-icon-document-add"
@click="handleCreate">添加</el-button>
</div>
</div>
<el-table :header-cell-style="{background:'#eef1f6',color:'#606266'}"
:data="tableData"
size="small"
@@ -33,29 +43,38 @@
label="时间"
min-width="15%"></el-table-column>
<el-table-column label="操作"
min-width="40%">
min-width="30%">
<template slot-scope="scope">
<el-button size="small"
type="success"
type="danger"
icon="el-icon-timer"
v-if="scope.row.isPublished===false"
@click="handlePublish(scope.$index, scope.row)"><i class="el-icon-timer el-icon--right"></i>发布</el-button>
@click="handlePublish(scope.$index, scope.row)"
circle>发布</el-button>
<el-button size="small"
type="warning"
type="primary"
icon="el-icon-delete-location"
v-if="scope.row.isPublished===true"
@click="handleRetireTask(scope.$index, scope.row)"><i class="el-icon-delete-location el-icon--right"></i>下线</el-button>
@click="handleRetireTask(scope.$index, scope.row)"
circle>下线</el-button>
<el-button size="small"
type="danger"
icon="el-icon-video-play"
v-if="scope.row.isPublished===true"
@click="handleRunTask(scope.$index, scope.row)"><i class="el-icon-video-play el-icon--right"></i>执行</el-button>
<el-dropdown size="small"
split-button
type="primary">
更多
<el-dropdown-menu slot="dropdown">
<el-dropdown-item @click.native.prevent="handleUpdate(scope.$index, scope.row)">修改</el-dropdown-item>
<el-dropdown-item @click.native.prevent="handleDelete(scope.$index, scope.row)">删除</el-dropdown-item>
</el-dropdown-menu>
</el-dropdown>
@click="handleRunTask(scope.$index, scope.row)"
circle>执行</el-button>
<el-button size="small"
type="warning"
icon="el-icon-edit"
v-if="scope.row.isPublished===false"
@click="handleUpdate(scope.$index, scope.row)"
circle>修改</el-button>
<el-button size="small"
type="success"
icon="el-icon-delete"
v-if="scope.row.isPublished===false"
@click="handleDelete(scope.$index, scope.row)"
circle>删除</el-button>
</template>
</el-table-column>
</el-table>
@@ -82,30 +101,41 @@ export default {
currentPage: 1,
pageSize: 10,
totalCount: 2,
keyword: null,
tableData: [],
};
},
methods: {
loadData: function () {
this.$http({
method: "GET",
url: "/dbswitch/admin/api/v1/assignment/list/" + this.currentPage + "/" + this.pageSize
}).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.tableData = res.data.data;
} else {
alert("加载任务列表失败:" + res.data.message);
}
method: "POST",
headers: {
'Content-Type': 'application/json'
},
url: "/dbswitch/admin/api/v1/assignment/list",
data: JSON.stringify({
searchText: this.keyword,
page: this.currentPage,
size: this.pageSize
})
}).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.tableData = res.data.data;
} else {
alert("加载任务列表失败:" + res.data.message);
}
},
function () {
console.log("failed");
console.log("load assignments list failed");
}
);
},
searchByKeyword: function () {
this.loadData();
},
boolFormatPublish (row, column) {
if (row.isPublished === true) {
return "是";
@@ -256,4 +286,27 @@ export default {
color: #c0c4cc;
cursor: pointer;
}
.assignment-list-top {
width: 100%;
display: flex;
justify-content: space-between;
}
.left-search-input-group {
width: calc(100% - 100px);
margin-right: auto;
display: flex;
justify-content: space-between;
}
.left-search-input {
width: 300px;
margin-right: auto;
margin: 10px 5px;
}
.right-add-button-group {
width: 100px;
margin-left: auto;
margin: 10px 5px;
}
</style>

View File

@@ -44,23 +44,34 @@
value="SYSTEM_SCHEDULED"></el-option>
</el-select>
</el-form-item>
<el-form-item label="Cron表达式"
<el-form-item label="执行周期"
label-width="240px"
style="width:65%"
v-if="createform.scheduleMode=='SYSTEM_SCHEDULED'">
<el-col :span="10">
<el-popover v-model="cronPopover">
<vueCron @change="changeCreateCronExpression"
@close="cronPopover=false"
i18n="cn" />
<el-input slot="reference"
:disabled=false
v-model="createform.cronExpression"
placeholder="点击选择或手动输入"
@click="cronPopover=true"
size="small" />
</el-popover>
</el-col>
<el-tooltip placement="top">
<div slot="content">
执行周期为CRON表达式即可以选择以下内置的周期也可以自行输入或粘贴合法的CRON表达式(最小间隔时间为2分钟)
</div>
<i class="el-icon-question"></i>
</el-tooltip>
<el-select v-model="createform.cronExpression"
filterable
allow-create>
<el-option label="每5分钟执行1次"
value="0 0/5 * * * ? *"></el-option>
<el-option label="每30分钟执行1次"
value="0 0/30 * * * ? *"></el-option>
<el-option label="每1小时执行1次"
value="0 0 0/1 * * ? *"></el-option>
<el-option label="每2小时执行1次"
value="0 0 0/2 * * ? *"></el-option>
<el-option label="每8小时执行1次"
value="0 0 0/8 * * ? *"></el-option>
<el-option label="每12小时执行1次"
value="0 0 0/12 * * ? *"></el-option>
<el-option label="每日0时执行1次"
value="0 0 0 1/1 * ? *"></el-option>
</el-select>
</el-form-item>
</div>
<div v-show="active == 2">
@@ -84,6 +95,7 @@
prop="sourceSchema"
style="width:65%">
<el-select v-model="createform.sourceSchema"
filterable
@change="selectCreateChangedSourceSchema"
placeholder="请选择">
<el-option v-for="(item,index) in sourceConnectionSchemas"
@@ -132,6 +144,7 @@
</el-tooltip>
<el-select placeholder="请选择表名"
multiple
filterable
v-model="createform.sourceTables">
<el-option v-for="(item,index) in sourceSchemaTables"
:key="index"
@@ -161,6 +174,7 @@
prop="targetSchema"
style="width:65%">
<el-select v-model="createform.targetSchema"
filterable
placeholder="请选择">
<el-option v-for="(item,index) in targetConnectionSchemas"
:key="index"
@@ -210,6 +224,7 @@
</el-form-item>
<el-form-item label="表名大小写转换"
label-width="240px"
:required=true
prop="tableNameCase"
style="width:45%">
<el-tooltip placement="top">
@@ -229,6 +244,7 @@
</el-form-item>
<el-form-item label="列名大小写转换"
label-width="240px"
:required=true
prop="columnNameCase"
style="width:45%">
<el-tooltip placement="top">
@@ -464,7 +480,7 @@
</el-dialog>
<el-dialog v-if="active == 4"
title="查看字段射关系"
title="查看字段射关系"
:visible.sync="columnNameMapperDialogVisible"
:showClose="false"
:before-close="handleClose">

View File

@@ -6,6 +6,12 @@
<div slot="header"
class="clearfix">
<span>任务安排列表</span>
<el-input placeholder="请输入关键字搜索"
v-model="keyword"
clearable=true
@change="changeSearchKeyword"
style="width:200px">
</el-input>
</div>
<div class="navsBox">
<ul>
@@ -55,11 +61,11 @@
<el-table-column label="日志"
min-width="15%">
<template slot-scope="props">
<el-button size="small"
type="danger"
@click="handleShowJobLogs(props.row.jobId)">
查看
</el-button>
<el-button size="small"
type="danger"
@click="handleShowJobLogs(props.row.jobId)">
查看
</el-button>
</template>
</el-table-column>
</el-table>
@@ -146,6 +152,7 @@ export default {
totalCount: 0,
currentTaskAssignmentPage: 1,
currentTaskAssignmentPageSize: 10,
keyword: null,
pageTaskAssignments: [],
pageTaskAssignmentsTotalCount: 0,
taskId: '请选择一个任务安排',
@@ -164,8 +171,16 @@ export default {
methods: {
loadPageTaskAssignments: function () {
this.$http({
method: "GET",
url: "/dbswitch/admin/api/v1/assignment/list/" + this.currentTaskAssignmentPage + "/" + this.currentTaskAssignmentPageSize
method: "POST",
headers: {
'Content-Type': 'application/json'
},
url: "/dbswitch/admin/api/v1/assignment/list",
data: JSON.stringify({
searchText: this.keyword,
page: this.currentTaskAssignmentPage,
size: this.currentTaskAssignmentPageSize
})
}).then(res => {
if (0 === res.data.code) {
this.pageTaskAssignments = res.data.data;
@@ -178,6 +193,9 @@ export default {
}
);
},
changeSearchKeyword: function () {
this.loadPageTaskAssignments();
},
handleLoadPageTaskAssignments: function (currentPage) {
this.currentTaskAssignmentPage = currentPage;
this.loadPageTaskAssignments();
@@ -383,5 +401,4 @@ export default {
padding: 10px;
width: calc(100% - 250px);
}
</style>

View File

@@ -48,19 +48,30 @@
label-width="240px"
style="width:65%"
v-if="updateform.scheduleMode=='SYSTEM_SCHEDULED'">
<el-col :span="10">
<el-popover v-model="cronPopover">
<vueCron @change="changeUpdateCronExpression"
@close="cronPopover=false"
i18n="cn" />
<el-input slot="reference"
:disabled=false
v-model="updateform.cronExpression"
placeholder="点击选择或手动输入"
@click="cronPopover=true"
size="small" />
</el-popover>
</el-col>
<el-tooltip placement="top">
<div slot="content">
执行周期为CRON表达式即可以选择以下内置的周期也可以自行输入或粘贴合法的CRON表达式(最小间隔时间为2分钟)
</div>
<i class="el-icon-question"></i>
</el-tooltip>
<el-select v-model="updateform.cronExpression"
filterable
allow-create>
<el-option label="每5分钟执行1次"
value="0 0/5 * * * ? *"></el-option>
<el-option label="每30分钟执行1次"
value="0 0/30 * * * ? *"></el-option>
<el-option label="每1小时执行1次"
value="0 0 0/1 * * ? *"></el-option>
<el-option label="每2小时执行1次"
value="0 0 0/2 * * ? *"></el-option>
<el-option label="每8小时执行1次"
value="0 0 0/8 * * ? *"></el-option>
<el-option label="每12小时执行1次"
value="0 0 0/12 * * ? *"></el-option>
<el-option label="每日0时执行1次"
value="0 0 0 1/1 * ? *"></el-option>
</el-select>
</el-form-item>
</div>
<div v-show="active == 2">
@@ -84,6 +95,7 @@
prop="sourceSchema"
style="width:65%">
<el-select v-model="updateform.sourceSchema"
filterable
@change="selectUpdateChangedSourceSchema"
placeholder="请选择">
<el-option v-for="(item,index) in sourceConnectionSchemas"
@@ -132,6 +144,7 @@
</el-tooltip>
<el-select placeholder="请选择表名"
multiple
filterable
v-model="updateform.sourceTables">
<el-option v-for="(item,index) in sourceSchemaTables"
:key="index"
@@ -186,6 +199,26 @@
:value=false></el-option>
</el-select>
</el-form-item>
<el-form-item label-width="240px"
:required=true
prop="targetDropTable"
style="width:65%">
<span slot="label">
<span style="color: red"><strong>删除同名表</strong> </span>
</span>
<el-tooltip placement="top">
<div slot="content">
当目标端存在同名表时,如果配置为“是”,则会删除同步表后再进行创建。如果修改了表或字段的映射关系,请将配置为“是”,否则任务执行时会因映射关系不匹配而报错。
</div>
<i class="el-icon-question"></i>
</el-tooltip>
<el-select v-model="updateform.targetDropTable">
<el-option label='是'
:value=true></el-option>
<el-option label='否'
:value=false></el-option>
</el-select>
</el-form-item>
<el-form-item label="数据处理批次大小"
label-width="240px"
:required=true
@@ -210,6 +243,7 @@
</el-form-item>
<el-form-item label="表名大小写转换"
label-width="240px"
:required=true
prop="tableNameCase"
style="width:45%">
<el-tooltip placement="top">
@@ -229,6 +263,7 @@
</el-form-item>
<el-form-item label="列名大小写转换"
label-width="240px"
:required=true
prop="columnNameCase"
style="width:45%">
<el-tooltip placement="top">
@@ -366,6 +401,7 @@
<el-descriptions-item label="目地端数据源">[{{updateform.targetConnectionId}}]{{targetConnection.name}}</el-descriptions-item>
<el-descriptions-item label="目地端schema">{{updateform.targetSchema}}</el-descriptions-item>
<el-descriptions-item label="只创建表">{{updateform.targetOnlyCreate}}</el-descriptions-item>
<el-descriptions-item label="删除同名表">{{updateform.targetDropTable}}</el-descriptions-item>
<el-descriptions-item label="数据处理批次量">{{updateform.batchSize}}</el-descriptions-item>
<el-descriptions-item label="表名大小写转换">
<span v-if="updateform.tableNameCase == 'NONE'">
@@ -469,7 +505,7 @@
</el-dialog>
<el-dialog v-if="active == 4"
title="查看字段射关系"
title="查看字段射关系"
:visible.sync="columnNameMapperDialogVisible"
:showClose="false"
:before-close="handleClose">
@@ -948,7 +984,7 @@ export default {
columnNameMapper: this.updateform.columnNameMapper,
tableNameCase: this.updateform.tableNameCase,
columnNameCase: this.updateform.columnNameCase,
targetDropTable: true,
targetDropTable: this.updateform.targetDropTable,
targetOnlyCreate: this.updateform.targetOnlyCreate,
batchSize: this.updateform.batchSize
}