!97 一些优化

* refactor: 重构表格分页组件,适配大数据量分页
* fix:定时任务修复
* feat: gaussdb单独提出来
This commit is contained in:
zongyangleo
2024-01-30 13:09:26 +00:00
committed by Coder慌
parent d0b71a1c40
commit fc1b9ef35d
12 changed files with 183 additions and 61 deletions

File diff suppressed because one or more lines are too long

View File

@@ -81,6 +81,13 @@
"font_class": "MSSQLNATIVE",
"unicode": "e600",
"unicode_decimal": 58880
},
{
"icon_id": "7699332",
"name": "gaussdb",
"font_class": "gauss",
"unicode": "e683",
"unicode_decimal": 59011
}
]
}

View File

@@ -9,13 +9,18 @@
</el-form-item>
<el-form-item prop="type" label="类型" required>
<el-select @change="changeDbType" style="width: 100%" v-model="form.type" placeholder="请选择数据库类型">
<el-option v-for="(dbTypeAndDialect, key) in getDbDialectMap()" :key="key" :value="dbTypeAndDialect[0]">
<SvgIcon :name="dbTypeAndDialect[1].getInfo().icon" :size="18" />
<el-option
v-for="(dbTypeAndDialect, key) in getDbDialectMap()"
:key="key"
:value="dbTypeAndDialect[0]"
:label="dbTypeAndDialect[1].getInfo().name"
>
<SvgIcon :name="dbTypeAndDialect[1].getInfo().icon" :size="20" />
{{ dbTypeAndDialect[1].getInfo().name }}
</el-option>
<template #prefix>
<SvgIcon :name="getDbDialect(form.type).getInfo().icon" :size="18" />
<SvgIcon :name="getDbDialect(form.type).getInfo().icon" :size="20" />
</template>
</el-select>
</el-form-item>

View File

@@ -443,7 +443,7 @@ onBeforeUnmount(() => {
* 设置editor高度和数据表高度
*/
const setHeight = () => {
state.dataTabsTableHeight = window.innerHeight - 270 + 'px';
state.dataTabsTableHeight = window.innerHeight - 253 + 'px';
state.tablesOpHeight = window.innerHeight - 225 + 'px';
};

View File

@@ -158,21 +158,62 @@
@data-delete="onRefresh"
></db-table-data>
<el-row type="flex" class="mt5" justify="center">
<el-pagination
small
:total="count"
@size-change="handleSizeChange"
@current-change="pageChange()"
layout="prev, pager, next, total, sizes, jumper"
v-model:current-page="pageNum"
v-model:page-size="pageSize"
:page-sizes="pageSizes"
></el-pagination>
<el-row type="flex" class="mt5" :gutter="10" justify="end" style="user-select: none">
<el-col :span="12">
<el-text
style="color: var(--el-color-info-light-3); font-size: 12px; margin-top: 5px"
class="is-truncated"
@click="handleCopySql(sql)"
:title="sql"
>{{ sql }}</el-text
>
</el-col>
<el-col :span="12">
<el-row :gutter="10" justify="center">
<el-link class="op-page" :underline="false" @click="pageNum = 1" :disabled="pageNum == 1" icon="DArrowLeft" title="首页" />
<el-link class="op-page" :underline="false" @click="pageNum = --pageNum || 1" :disabled="pageNum == 1" icon="Back" title="上一页" />
<div class="op-page">
<el-input-number
style="width: 50px"
:controls="false"
:min="1"
v-model="state.setPageNum"
size="small"
@blur="handleSetPageNum"
@keydown.enter="handleSetPageNum"
/>
</div>
<el-link class="op-page" :underline="false" @click="++pageNum" icon="Right" />
<el-link class="op-page" :underline="false" @click="handleEndPage" icon="DArrowRight" />
<div style="width: 90px; margin-left: 20px" class="op-page">
<el-select size="small" :default-first-option="true" v-model="pageSize" @change="handleSizeChange">
<el-option
style="font-size: 12px; height: 24px; line-height: 24px"
v-for="(op, i) in pageSizes"
:key="i"
:label="op + '条/页'"
:value="op"
/>
</el-select>
</div>
<el-link
class="op-page"
style="margin-left: 20px"
v-if="!state.counting"
:underline="false"
@click="handleCount"
icon="Stopwatch"
title="计数"
/>
<el-link class="op-page" style="margin-left: 20px" v-if="state.counting" :underline="false" title="计数中...">
<el-icon class="is-loading">
<Loading />
</el-icon>
</el-link>
<el-text class="op-page" style="font-size: 12px" v-if="state.showTotal">总 {{ state.total }} 条</el-text>
</el-row>
</el-col>
</el-row>
<div style="padding: 0 10px">
<span style="color: var(--el-color-info-light-3)" class="font10 el-text el-text--small is-truncated">{{ state.sql }}</span>
</div>
<el-dialog v-model="conditionDialog.visible" :title="conditionDialog.title" width="420px">
<el-row>
@@ -242,6 +283,7 @@ import { DbDialect, getDbDialect } from '@/views/ops/db/dialect';
import SvgIcon from '@/components/svgIcon/index.vue';
import ColumnFormItem from './ColumnFormItem.vue';
import { useEventListener, useStorage } from '@vueuse/core';
import { copyToClipboard } from '@/common/utils/string';
const props = defineProps({
dbId: {
@@ -290,7 +332,10 @@ const state = reactive({
defaultPageSize * 40,
defaultPageSize * 80,
],
count: 0,
setPageNum: 0,
total: 0,
showTotal: 0,
counting: false,
selectionDatas: [] as any,
condPopVisible: false,
columnNameSearch: '',
@@ -314,7 +359,7 @@ const state = reactive({
dbDialect: {} as DbDialect,
});
const { datas, condition, loading, columns, pageNum, pageSize, pageSizes, count, hasUpdatedFileds, conditionDialog, addDataDialog, dbDialect } = toRefs(state);
const { datas, condition, loading, columns, pageNum, pageSize, pageSizes, sql, hasUpdatedFileds, conditionDialog, addDataDialog, dbDialect } = toRefs(state);
watch(
() => props.tableHeight,
@@ -347,18 +392,19 @@ const onRefresh = async () => {
await selectData();
};
/**
* 数据tab修改页数
*/
const pageChange = async () => {
await selectData();
};
watch(
() => state.pageNum,
async () => {
await selectData();
}
);
/**
* 单表数据信息查询数据
*/
const selectData = async () => {
state.loading = true;
state.setPageNum = state.pageNum;
const dbInst = getNowDbInst();
const db = props.dbName;
const table = props.tableName;
@@ -371,16 +417,10 @@ const selectData = async () => {
state.columns = columns;
}
const countRes = await dbInst.runSql(db, dbInst.getDefaultCountSql(table, state.condition));
state.count = parseInt(countRes.res[0].count || countRes.res[0].COUNT || 0);
let sql = dbInst.getDefaultSelectSql(db, table, state.condition, state.orderBy, state.pageNum, state.pageSize);
state.sql = sql;
if (state.count > 0) {
const colAndData: any = await dbInst.runSql(db, sql);
state.datas = colAndData.res;
} else {
state.datas = [];
}
const colAndData: any = await dbInst.runSql(db, sql);
state.datas = colAndData.res;
} finally {
state.loading = false;
}
@@ -392,6 +432,38 @@ const handleSizeChange = async (size: any) => {
await selectData();
};
const handleEndPage = async () => {
await handleCount();
state.pageNum = Math.ceil(state.total / state.pageSize);
await selectData();
};
const handleSetPageNum = async () => {
state.pageNum = state.setPageNum;
await selectData();
};
const handleCount = async () => {
state.counting = true;
try {
const db = props.dbName;
const table = props.tableName;
const dbInst = getNowDbInst();
const countRes = await dbInst.runSql(db, dbInst.getDefaultCountSql(table, state.condition));
state.total = parseInt(countRes.res[0].count || countRes.res[0].COUNT || 0);
state.showTotal = true;
} catch (e) {
/* empty */
}
state.counting = false;
};
const handleCopySql = async (sql: string) => {
await copyToClipboard(sql);
ElMessage.success('复制成功');
};
// 完整的条件,每次选中后会重置条件框内容,故需要这个变量在获取建议时将文本框内容保存
let completeCond = '';
// 是否存在列建议
@@ -586,4 +658,8 @@ const addRow = async () => {
};
</script>
<style lang="scss"></style>
<style lang="scss">
.op-page {
margin-left: 5px;
}
</style>

View File

@@ -0,0 +1,17 @@
import { PostgresqlDialect } from '@/views/ops/db/dialect/postgres_dialect';
import { DialectInfo } from '@/views/ops/db/dialect/index';
let gsDialectInfo: DialectInfo;
export class GaussDialect extends PostgresqlDialect {
getInfo(): DialectInfo {
if (gsDialectInfo) {
return gsDialectInfo;
}
gsDialectInfo = {} as DialectInfo;
Object.assign(gsDialectInfo, super.getInfo());
gsDialectInfo.icon = 'iconfont icon-gauss';
gsDialectInfo.name = 'GaussDB';
return gsDialectInfo;
}
}

View File

@@ -5,6 +5,7 @@ import { OracleDialect } from '@/views/ops/db/dialect/oracle_dialect';
import { MariadbDialect } from '@/views/ops/db/dialect/mariadb_dialect';
import { SqliteDialect } from '@/views/ops/db/dialect/sqlite_dialect';
import { MssqlDialect } from '@/views/ops/db/dialect/mssql_dialect';
import { GaussDialect } from '@/views/ops/db/dialect/gauss_dialect';
export interface sqlColumnType {
udtName: string;
@@ -116,6 +117,7 @@ export const DbType = {
mysql: 'mysql',
mariadb: 'mariadb',
postgresql: 'postgres',
gauss: 'gauss',
dm: 'dm', // 达梦
oracle: 'oracle',
sqlite: 'sqlite',
@@ -126,7 +128,7 @@ export const DbType = {
export const noSchemaTypes = [DbType.mysql, DbType.mariadb, DbType.sqlite];
// 有schema层的数据库
export const schemaDbTypes = [DbType.postgresql, DbType.dm, DbType.oracle, DbType.mssql];
export const schemaDbTypes = [DbType.postgresql, DbType.gauss, DbType.dm, DbType.oracle, DbType.mssql];
export const editDbTypes = [...noSchemaTypes, ...schemaDbTypes];
@@ -225,6 +227,7 @@ export const getDbDialect = (dbType: string): DbDialect => {
registerDbDialect(DbType.mysql, mysqlDialect);
registerDbDialect(DbType.mariadb, new MariadbDialect());
registerDbDialect(DbType.postgresql, new PostgresqlDialect());
registerDbDialect(DbType.gauss, new GaussDialect());
registerDbDialect(DbType.dm, new DMDialect());
registerDbDialect(DbType.oracle, new OracleDialect());
registerDbDialect(DbType.sqlite, new SqliteDialect());