mirror of
https://gitee.com/dromara/mayfly-go
synced 2025-11-02 15:30:25 +08:00
fix: 修复数据库表数据横向滚动后切换tab导致表头错位&数据取消居中显示
This commit is contained in:
@@ -10,7 +10,7 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"@element-plus/icons-vue": "^2.3.1",
|
||||
"@vueuse/core": "^10.9.0",
|
||||
"@vueuse/core": "^10.10.0",
|
||||
"asciinema-player": "^3.7.1",
|
||||
"axios": "^1.6.2",
|
||||
"clipboard": "^2.0.11",
|
||||
@@ -22,8 +22,8 @@
|
||||
"jsencrypt": "^3.3.2",
|
||||
"lodash": "^4.17.21",
|
||||
"mitt": "^3.0.1",
|
||||
"monaco-editor": "^0.48.0",
|
||||
"monaco-sql-languages": "^0.11.0",
|
||||
"monaco-editor": "^0.49.0",
|
||||
"monaco-sql-languages": "^0.12.0",
|
||||
"monaco-themes": "^0.4.4",
|
||||
"nprogress": "^0.2.0",
|
||||
"pinia": "^2.1.7",
|
||||
|
||||
@@ -15,7 +15,7 @@ const config = {
|
||||
baseWsUrl: `${(window as any).globalConfig.BaseWsUrl || `${location.protocol == 'https:' ? 'wss:' : 'ws:'}//${getBaseApiUrl()}`}/api`,
|
||||
|
||||
// 系统版本
|
||||
version: 'v1.8.6',
|
||||
version: 'v1.8.7',
|
||||
};
|
||||
|
||||
export default config;
|
||||
|
||||
@@ -177,6 +177,7 @@
|
||||
:db-name="dt.db"
|
||||
:table-name="dt.params.table"
|
||||
:table-height="state.dataTabsTableHeight"
|
||||
:ref="(el: any) => (dt.componentRef = el)"
|
||||
></db-table-data-op>
|
||||
|
||||
<db-sql-editor
|
||||
@@ -185,6 +186,7 @@
|
||||
:db-name="dt.db"
|
||||
:sql-name="dt.params.sqlName"
|
||||
@save-sql-success="reloadSqls"
|
||||
:ref="(el: any) => (dt.componentRef = el)"
|
||||
>
|
||||
</db-sql-editor>
|
||||
|
||||
@@ -579,7 +581,7 @@ const loadTableData = async (db: any, dbName: string, tableName: string) => {
|
||||
}
|
||||
changeDb(db, dbName);
|
||||
|
||||
const key = `${db.id}:\`${dbName}\`.${tableName}`;
|
||||
const key = `tableData:${db.id}.${dbName}.${tableName}`;
|
||||
let tab = state.tabs.get(key);
|
||||
state.activeName = key;
|
||||
// 如果存在该表tab,则直接返回
|
||||
@@ -614,7 +616,7 @@ const addQueryTab = async (db: any, dbName: string, sqlName: string = '') => {
|
||||
// 存在sql模板名,则该模板名只允许一个tab
|
||||
if (sqlName) {
|
||||
label = `查询-${sqlName}`;
|
||||
key = `查询:${dbId}:${dbName}.${sqlName}`;
|
||||
key = `query:${dbId}.${dbName}.${sqlName}`;
|
||||
} else {
|
||||
let count = 1;
|
||||
state.tabs.forEach((v) => {
|
||||
@@ -623,7 +625,7 @@ const addQueryTab = async (db: any, dbName: string, sqlName: string = '') => {
|
||||
}
|
||||
});
|
||||
label = `新查询-${count}`;
|
||||
key = `新查询${count}:${dbId}:${dbName}`;
|
||||
key = `query:${count}.${dbId}.${dbName}`;
|
||||
}
|
||||
state.activeName = key;
|
||||
let tab = state.tabs.get(key);
|
||||
@@ -660,7 +662,7 @@ const addTablesOpTab = async (db: any) => {
|
||||
changeDb(db, dbName);
|
||||
|
||||
const dbId = db.id;
|
||||
let key = `表操作:${dbId}:${dbName}.tablesOp`;
|
||||
let key = `tablesOp:${dbId}.${dbName}`;
|
||||
state.activeName = key;
|
||||
|
||||
let tab = state.tabs.get(key);
|
||||
@@ -691,15 +693,22 @@ const onRemoveTab = (targetName: string) => {
|
||||
if (tabName !== targetName) {
|
||||
continue;
|
||||
}
|
||||
|
||||
state.tabs.delete(targetName);
|
||||
if (activeName != targetName) {
|
||||
break;
|
||||
}
|
||||
|
||||
// 如果删除的tab是当前激活的tab,则切换到前一个或后一个tab
|
||||
const nextTab = tabNames[i + 1] || tabNames[i - 1];
|
||||
if (nextTab) {
|
||||
activeName = nextTab;
|
||||
} else {
|
||||
activeName = '';
|
||||
}
|
||||
state.tabs.delete(targetName);
|
||||
state.activeName = activeName;
|
||||
onTabChange();
|
||||
break;
|
||||
}
|
||||
};
|
||||
|
||||
@@ -719,6 +728,9 @@ const onTabChange = () => {
|
||||
registerDbCompletionItemProvider(nowTab.dbId, nowTab.db, nowTab.params.dbs, nowDbInst.value.type);
|
||||
}
|
||||
|
||||
// 激活当前tab(需要调用DbTableData组件的active,否则表头与数据会出现错位,暂不知为啥,先这样处理)
|
||||
nowTab?.componentRef?.active();
|
||||
|
||||
if (dbConfig.value.locationTreeNode) {
|
||||
locationNowTreeNode(nowTab);
|
||||
}
|
||||
|
||||
@@ -23,7 +23,10 @@ export const dbApi = {
|
||||
if (process.env.NODE_ENV === 'development') {
|
||||
console.log(param.sql);
|
||||
}
|
||||
param.sql = Base64.encode(param.sql);
|
||||
// 非base64编码sql,则进行base64编码(refreshToken时,会重复调用该方法,故简单判断下)
|
||||
if (!Base64.isValid(param.sql)) {
|
||||
param.sql = Base64.encode(param.sql);
|
||||
}
|
||||
}
|
||||
return param;
|
||||
}),
|
||||
|
||||
@@ -52,7 +52,7 @@
|
||||
|
||||
<Pane :size="100 - state.editorSize">
|
||||
<div class="mt5 sql-exec-res h100">
|
||||
<el-tabs class="h100 w100" v-if="state.execResTabs.length > 0" @tab-remove="onRemoveTab" v-model="state.activeTab">
|
||||
<el-tabs class="h100 w100" v-if="state.execResTabs.length > 0" @tab-remove="onRemoveTab" @tab-change="active" v-model="state.activeTab">
|
||||
<el-tab-pane class="h100" closable v-for="dt in state.execResTabs" :label="dt.id" :name="dt.id" :key="dt.id">
|
||||
<template #label>
|
||||
<el-popover :show-after="1000" placement="top-start" title="执行信息" trigger="hover" :width="300">
|
||||
@@ -700,6 +700,19 @@ const initMonacoEditor = () => {
|
||||
},
|
||||
});
|
||||
};
|
||||
|
||||
const active = () => {
|
||||
const resTab = state.execResTabs[state.activeTab - 1];
|
||||
if (!resTab || !resTab.dbTableRef) {
|
||||
return;
|
||||
}
|
||||
|
||||
resTab.dbTableRef?.active();
|
||||
};
|
||||
|
||||
defineExpose({
|
||||
active,
|
||||
});
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
|
||||
@@ -152,6 +152,10 @@ const getEditorLangByValue = (value: any) => {
|
||||
<style lang="scss">
|
||||
.string-input-container {
|
||||
position: relative;
|
||||
|
||||
.el-input__wrapper {
|
||||
padding: 1px 3px;
|
||||
}
|
||||
}
|
||||
.string-input-container-show-icon {
|
||||
.el-input__inner {
|
||||
@@ -174,6 +178,10 @@ const getEditorLangByValue = (value: any) => {
|
||||
.el-input__prefix {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.el-input__wrapper {
|
||||
padding: 1px 3px;
|
||||
}
|
||||
}
|
||||
|
||||
.edit-time-picker-popper {
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
fixed
|
||||
class="table"
|
||||
:row-event-handlers="rowEventHandlers"
|
||||
@scroll="onTableScroll"
|
||||
>
|
||||
<template #header="{ columns }">
|
||||
<div v-for="(column, i) in columns" :key="i">
|
||||
@@ -59,9 +60,7 @@
|
||||
</div>
|
||||
|
||||
<div v-else class="header-column-title">
|
||||
<b class="el-text">
|
||||
{{ column.title }}
|
||||
</b>
|
||||
<b class="el-text"> {{ column.title }} </b>
|
||||
</div>
|
||||
|
||||
<!-- 字段列右部分内容 -->
|
||||
@@ -96,7 +95,7 @@
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div v-else :class="isUpdated(rowIndex, column.dataKey) ? 'update_field_active' : ''">
|
||||
<div v-else :class="isUpdated(rowIndex, column.dataKey) ? 'update_field_active ml2 mr2' : 'ml2 mr2'">
|
||||
<span v-if="rowData[column.dataKey!] === null" style="color: var(--el-color-info-light-5)"> NULL </span>
|
||||
|
||||
<span v-else :title="rowData[column.dataKey!]" class="el-text el-text--small is-truncated">
|
||||
@@ -486,7 +485,7 @@ const setTableColumns = (columns: any) => {
|
||||
dataKey: columnName,
|
||||
width: DbInst.flexColumnWidth(columnName, state.datas),
|
||||
title: columnName,
|
||||
align: 'center',
|
||||
align: x.dataType == DataType.Number ? 'right' : 'left',
|
||||
headerClass: 'table-column',
|
||||
class: 'table-column',
|
||||
sortable: true,
|
||||
@@ -841,11 +840,23 @@ const triggerRefresh = () => {
|
||||
}
|
||||
};
|
||||
|
||||
const scrollLeftValue = ref(0);
|
||||
const onTableScroll = (param: any) => {
|
||||
scrollLeftValue.value = param.scrollLeft;
|
||||
};
|
||||
/**
|
||||
* 激活表格,恢复滚动位置,否则会造成表头与数据单元格错位(暂不知为啥,先这样解决)
|
||||
*/
|
||||
const active = () => {
|
||||
setTimeout(() => tableRef.value.scrollToLeft(scrollLeftValue.value));
|
||||
};
|
||||
|
||||
const getNowDbInst = () => {
|
||||
return DbInst.getInst(state.dbId);
|
||||
};
|
||||
|
||||
defineExpose({
|
||||
active,
|
||||
submitUpdateFields,
|
||||
cancelUpdateFields,
|
||||
});
|
||||
|
||||
@@ -48,6 +48,21 @@
|
||||
<el-tooltip :show-after="500" class="box-item" effect="dark" content="commit" placement="top">
|
||||
<el-link @click="onCommit()" type="success" icon="CircleCheck" :underline="false"> </el-link>
|
||||
</el-tooltip>
|
||||
<el-divider direction="vertical" border-style="dashed" />
|
||||
|
||||
<!-- 表数据展示配置 -->
|
||||
<el-popover
|
||||
popper-style="max-height: 550px; overflow: auto; max-width: 450px"
|
||||
placement="bottom"
|
||||
width="auto"
|
||||
title="展示配置"
|
||||
trigger="click"
|
||||
>
|
||||
<el-checkbox v-model="dbConfig.showColumnComment" label="显示字段备注" :true-value="true" :false-value="false" size="small" />
|
||||
<template #reference>
|
||||
<el-link type="primary" icon="setting" :underline="false"></el-link>
|
||||
</template>
|
||||
</el-popover>
|
||||
|
||||
<el-divider direction="vertical" border-style="dashed" />
|
||||
|
||||
@@ -243,7 +258,7 @@ import { DbInst } from '@/views/ops/db/db';
|
||||
import DbTableData from './DbTableData.vue';
|
||||
import { DbDialect } from '@/views/ops/db/dialect';
|
||||
import SvgIcon from '@/components/svgIcon/index.vue';
|
||||
import { useEventListener } from '@vueuse/core';
|
||||
import { useEventListener, useStorage } from '@vueuse/core';
|
||||
import { copyToClipboard } from '@/common/utils/string';
|
||||
import DbTableDataForm from './DbTableDataForm.vue';
|
||||
|
||||
@@ -273,6 +288,8 @@ const condDialogInputRef: Ref = ref(null);
|
||||
|
||||
const defaultPageSize = DbInst.DefaultLimit;
|
||||
|
||||
const dbConfig = useStorage('dbConfig', { showColumnComment: false });
|
||||
|
||||
const state = reactive({
|
||||
datas: [],
|
||||
sql: '', // 当前数据tab执行的sql
|
||||
@@ -605,6 +622,10 @@ const onShowAddDataDialog = async () => {
|
||||
state.addDataDialog.title = `添加'${props.tableName}'表数据`;
|
||||
state.addDataDialog.visible = true;
|
||||
};
|
||||
|
||||
defineExpose({
|
||||
active: () => dbTableRef.value.active(),
|
||||
});
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
|
||||
@@ -450,8 +450,8 @@ export class DbInst {
|
||||
return;
|
||||
}
|
||||
|
||||
// 获取列名称的长度 加上排序图标长度、abc为字段类型简称占位符
|
||||
const columnWidth: number = getTextWidth(prop + 'abc') + 23;
|
||||
// 获取列名称的长度 加上排序图标长度、abc为字段类型简称占位符、排序图标等
|
||||
const columnWidth: number = getTextWidth(prop + 'abc') + 10;
|
||||
// prop为该列的字段名(传字符串);tableData为该表格的数据源(传变量);
|
||||
if (!tableData || !tableData.length || tableData.length === 0 || tableData === undefined) {
|
||||
return columnWidth;
|
||||
@@ -471,7 +471,7 @@ export class DbInst {
|
||||
maxWidthText = nowText;
|
||||
}
|
||||
}
|
||||
const contentWidth: number = getTextWidth(maxWidthText) + 15;
|
||||
const contentWidth: number = getTextWidth(maxWidthText) + 3;
|
||||
const flexWidth: number = contentWidth > columnWidth ? contentWidth : columnWidth;
|
||||
return flexWidth > 500 ? 500 : flexWidth;
|
||||
};
|
||||
@@ -601,6 +601,11 @@ export class TabInfo {
|
||||
*/
|
||||
params: any;
|
||||
|
||||
/**
|
||||
* 组件ref
|
||||
*/
|
||||
componentRef: any;
|
||||
|
||||
getNowDbInst() {
|
||||
return DbInst.getInst(this.dbId);
|
||||
}
|
||||
|
||||
@@ -71,9 +71,9 @@ export enum DataType {
|
||||
/** 列数据类型角标 */
|
||||
export const ColumnTypeSubscript = {
|
||||
/** 字符串 */
|
||||
string: 'abc',
|
||||
string: 'ab',
|
||||
/** 数字 */
|
||||
number: '123',
|
||||
number: '12',
|
||||
/** 日期 */
|
||||
date: 'icon-clock',
|
||||
/** 时间 */
|
||||
|
||||
@@ -497,20 +497,27 @@ const onRemoveTab = (targetName: string) => {
|
||||
if (tabName !== targetName) {
|
||||
continue;
|
||||
}
|
||||
|
||||
state.tabs.delete(targetName);
|
||||
let info = state.tabs.get(targetName);
|
||||
if (info) {
|
||||
terminalRefs[info.key]?.close();
|
||||
}
|
||||
|
||||
if (activeTermName != targetName) {
|
||||
break;
|
||||
}
|
||||
|
||||
// 如果删除的tab是当前激活的tab,则切换到前一个或后一个tab
|
||||
const nextTab = tabNames[i + 1] || tabNames[i - 1];
|
||||
if (nextTab) {
|
||||
activeTermName = nextTab;
|
||||
} else {
|
||||
activeTermName = '';
|
||||
}
|
||||
let info = state.tabs.get(targetName);
|
||||
if (info) {
|
||||
terminalRefs[info.key]?.close();
|
||||
}
|
||||
|
||||
state.tabs.delete(targetName);
|
||||
state.activeTermName = activeTermName;
|
||||
// onTabChange();
|
||||
break;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -28,7 +28,7 @@ require (
|
||||
github.com/pquerna/otp v1.4.0
|
||||
github.com/redis/go-redis/v9 v9.5.1
|
||||
github.com/robfig/cron/v3 v3.0.1 // 定时任务
|
||||
github.com/sijms/go-ora/v2 v2.8.17
|
||||
github.com/sijms/go-ora/v2 v2.8.19
|
||||
github.com/stretchr/testify v1.9.0
|
||||
github.com/veops/go-ansiterm v0.0.5
|
||||
go.mongodb.org/mongo-driver v1.15.0 // mongo
|
||||
|
||||
@@ -297,7 +297,7 @@ func (d *dbAppImpl) DumpDb(ctx context.Context, reqParam *dto.DumpDb) error {
|
||||
|
||||
// 生成insert sql,数据在索引前,加速insert
|
||||
if reqParam.DumpData {
|
||||
writer.WriteString(fmt.Sprintf("\n-- ----------------------------\n-- 表记录: %s \n-- ----------------------------\n", tableName))
|
||||
writer.WriteString(fmt.Sprintf("\n-- ----------------------------\n-- 表数据: %s \n-- ----------------------------\n", tableName))
|
||||
|
||||
dumpHelper.BeforeInsert(writer, quoteTableName)
|
||||
// 获取列信息
|
||||
|
||||
@@ -26,7 +26,7 @@ type ResourceAuthCert interface {
|
||||
// GetAuthCert 根据授权凭证名称获取授权凭证
|
||||
GetAuthCert(authCertName string) (*entity.ResourceAuthCert, error)
|
||||
|
||||
// GetResourceAuthCert 获取资源授权凭证,默认获取特权账号,若没有则返回第一个
|
||||
// GetResourceAuthCert 获取资源授权凭证,优先获取默认账号,若不存在默认账号则返回特权账号,都不存在则返回第一个
|
||||
GetResourceAuthCert(resourceType entity.TagType, resourceCode string) (*entity.ResourceAuthCert, error)
|
||||
|
||||
// FillAuthCertByAcs 根据授权凭证列表填充资源的授权凭证信息
|
||||
@@ -224,6 +224,12 @@ func (r *resourceAuthCertAppImpl) GetResourceAuthCert(resourceType entity.TagTyp
|
||||
return nil, errorx.NewBiz("该资源不存在授权凭证账号")
|
||||
}
|
||||
|
||||
for _, resourceAuthCert := range resourceAuthCerts {
|
||||
if resourceAuthCert.Type == entity.AuthCertTypePrivateDefault {
|
||||
return r.decryptAuthCert(resourceAuthCert)
|
||||
}
|
||||
}
|
||||
|
||||
for _, resourceAuthCert := range resourceAuthCerts {
|
||||
if resourceAuthCert.Type == entity.AuthCertTypePrivileged {
|
||||
return r.decryptAuthCert(resourceAuthCert)
|
||||
|
||||
@@ -4,7 +4,7 @@ import "fmt"
|
||||
|
||||
const (
|
||||
AppName = "mayfly-go"
|
||||
Version = "v1.8.6"
|
||||
Version = "v1.8.7"
|
||||
)
|
||||
|
||||
func GetAppInfo() string {
|
||||
|
||||
Reference in New Issue
Block a user